1 Rationale and Objectives

This document details the modeling workflow implemented for estimating dissolved and equilibrium N2O concentrations and saturation ratios using the 2017 Nation Lakes Assessment (NLA) survey data. The NLA sampling sites were distributed among the target population of US lakes (in the lower 48 states) according to a probabilistic survey design with samples stratified among categories of lake surface area, WSA9 ecoregion, and US state (excluding AK and HI). Due to the stratification scheme, some types of lakes in the sample population were intentionally over-represented (e.g., large lakes) and some were under-represented (e.g., small lakes) relative to the target population. Due to the unequal probability design, inferences from the sample had to be adjusted for inferences on the broader populations of interest (e.g, National-, state-, ecoregion-, and size class-specific estimates).

The concept of the “complete data likelihood” is useful for conceptualizing biases arising from sampling design (Zachmann et al. 2022; Gelman et al. 2014 Ch. 8; Link and Barker 2010). For the NLA survey data, the population of US lakes in the lower 48 states larger than 4 hectares was considered the complete data and the probabilistic samples were considered a subset of that complete data. The portion of US lakes not included in the sample were considered “missing” from the complete data not at random, but conditional on the pre-specified design (stratification) variables. This non-random missingness was not ignorable for the purpose of making inferences from the sample to the target population. In a model-based framework, however, including the design parameters as predictors in a regression model is one way to adjust for the missingness. For a thorough and recent treatment of this concept in the context of national surveys of environmental resources, refer to (Zachmann et al. 2022). This concept is a key motivator for the increasingly popular mulitilevel regression with poststratification (MRP) approach to model-based inference [Gelman et al. (2014); Gelmant_etal_2020 Ch. 17].

The following workflow illustrates our model-based approach, based largely on the logic of MRP, but with an elaboration on the poststratification step to enable eventual estimates of total gas flux at the population level, which required scaling up from lake-level estimates. The typical MRP process is carried out in two steps. The first step is to fit regression models for the response variables of interest (e.g., dissolved N2O, equilibrium N2O) conditional on the survey design variables ┼(i.e., ecoregion, state, lake size). The second step is post-stratfication, wherein the posterior parameter estimates from the regression model for the sample population are weighted based on their known or assumed distribution in the population of interest [i.e., post-stratification table; Gelman, Hill, and Vehtari (2020) Ch. 17]. The poststratification table in our case, for example, would be a population summary of lakes among the design variables: ecoregion, state, and size category. However, because we eventually needed lake-level estmates, instead of predicting to a postratification table, we predicted to each individual lake in the population of interest. This meant predicting to the full target population of 465,897 natural and man made US lakes larger than 4 hectares in the lower 48 states. These predictions were assumed relevant to average conditions during the “index period” for each lake in 2017. Details about the sampling frame as well as the target population are further clarified in the workbook below with data summaries and code.

For the regressions, we used multilevel models fit in a fully Bayesian fashion Multilevel models are thought to work well in this context because they provide regularized estimates along the design groupings, which can improve out-of-sample inferences (McElreath 2020). Inferences for lake types that may be missing from the sample, but are part of the population of interest are also straightforward using this approach (Gelman, Hill, and Vehtari 2020 Ch. 17; McElreath 2020). More information these models, their specific parameters, R code, fit evaluations, and resulting inferences are presented in this document.

The overriding objective of the modeling effort was to provide population level estimates for (1) dissolved and equilibrium N2O concentrations; (2) the N2O saturation ratio (i.e., dissolved N2O/equilibrium N2O); and (3) the proportion of under-saturated water bodies (i.e., saturation ratio < 1). The estimates would also be used to later estimate the total flux of N2O gas attributable to the target population of lakes over the index period. The saturation ratio estimates were calculated as a derived quantity based on the ratio of modeled dissolved to equilibrium N2O. Because dissolved and equilibrium N2O were observed on the same sample units (lake sites), we developed models for estimating their joint distribution. The response variable in the models was, therefore, multivariate to account for potential statistical dependencies between dissolved and equilibrium N2O due to, for example, common dependencies on geography. Although point predictions of the mean marginal probabilities from separate models could be comparable, a joint model allowing correlated observation-level errors (i.e., residuals) was expected to better capture uncertainty and potentially improve out-of-sample predictions, should the variables be conditionally correlated (Warton et al. 2015; Poggiato et al. 2021). All of the models fit were constructed using the brms package (Bürkner 2017) in R (R Core Team 2021) as an interface to Stan, a software package for fitting fully Bayesian models via Hamiltonian Monte Carlo [HMC; Team (2018b); Team (2018c); Team (2018a)].

2 Data

As explained in a previous data munging document document (https://github.com/USEPA/DissolvedGasNla/blob/master/scripts/dgIndicatorAnalysis.html), duplicate dissolved gas samples were collected at a depth of ~0.1m at designated index sites distributed across 1091 lakes nationwide, of which 95 were sampled twice as repeat visits. This randomly selected subset of revisit sites was used as a test set for assessing model fit and out-of-sample performance.

Gas samples were analyzed via gas chromotography and concentrations were recorded to the nearest 0.001 nmol/L. The samples were collected under a stratified, unequal probability design and each gas observation was indexed to an individual lake selected with unequal probability from 5 different lake size categories, \(j \in j=1,...,J = 5\), according to surface area (ha), and from within a state, \(k \in k=1,...,K = 48\), situated within an aggregated, WSA9 or Omernik ecoregion, \(l \in l=1,...,L = 9\). All 9 WSA9 ecoregions were represented in the sample, including Xeric (XER), Western Mountain (WMT), Northern Plains (NPL), Southern Plains (SPL), Temperate Plains (TPL), Coastal Plains (CPL), Upper Midwest (UMW), Northern Appalachian (NAP), and Southern Appalachian (SAP) regions. As shown below, the data from the initial and revisit samples were separately compiled into data frame objects in \(\textbf{R}\), with \(n=984\) and \(n=95\) rows, respectively, of gas observations indexed to the survey design variables and several potentially relevant covariates.

2.1 Import

The gas data and covariates were previously described and munged at https://github.com/USEPA/DissolvedGasNla/blob/master/scripts/dataMunge.html. That dataset was imported below.

load( file = paste0( localPath,
              "/Environmental Protection Agency (EPA)/",
              "ORD NLA17 Dissolved Gas - Documents/",
              "inputData/dg.2021-02-01.RData")
      )

save(dg, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/dg.rda") 

From the imported dataset, a new data frame for modeling was constructed from the original file including only the variables of interest: (1) the N2O gas observations; (2) the survey design variables indexed to those observations; and (3) additional covariates considered potentially useful for improving the fit of the model. The data frame below excluded the second-visit observations, which would later be used for model checking. Some variables from the imported data were renamed for convenience. In addition, the NO3 covariate was rounded according to the documented measurement precision. An alternative version of the NO3 covariate was also created in this step by log-transforming and re-coding it as an ordered factor with five levels at hand-drawn cut points. The left-most cut point separated observations below the detection limit from the completely observed samples. The remaining cut points in the positive direction were drawn at approximately equal distances along the log scale. Finally, it should be noted that one lake that was sampled was missing information on the N2O gas measurements and it was removed from the data frame.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/dg.rda")

dg %>%
  filter(!is.na(dissolved.n2o.nmol)) %>% # 1 obs with missing measurement
  nrow() # number of observations before filtering
[1] 1185
df_model <- dg %>%
  filter(!is.na(dissolved.n2o.nmol)) %>%
  filter(sitetype == "PROB") %>% # probability samples only
  filter(visit.no == 1) %>%
  mutate(n2o = round(dissolved.n2o.nmol, 2),
         n2o_eq = round(sat.n2o.nmol, 2),
         n2o_sat = n2o.sat.ratio,
         n2o_em = e.n2o.nmol.d,
         n2o_flux = f.n2o.m.d,
         WSA9 = factor(ag.eco9),
         state = factor(state.abb[match(state.nm, state.name)]),
         area_ha = area.ha,
         log_area = log(area_ha),
         chla = chla.result,
         log_chla = log(chla),
         elev = elevation,
         log_elev = log(elev + 1),
         do_surf = o2.surf,
         log_do = log(do_surf),
         bf_max = max.bf,
         sqrt_bf = sqrt(bf_max),
         size_cat = recode(area.cat6, 
                           "(1,4]" = "min_4" ,
                           "(10,20]" = "10_20",
                           "(20,50]" = "20_50",
                           "(4,10]" = "4_10",
                           ">50" = "50_max")) %>%
  mutate(size_cat = factor(size_cat,
                           levels = c("min_4", "4_10", "10_20", "20_50", "50_max"),
                           ordered = TRUE)) %>%
  mutate(no3 = ifelse(nitrate.n.result <= 0.0005, 0.0005, round(nitrate.n.result, 4))) %>%# 1/2 mdl 0.01
  mutate(no3_cat = cut(log(no3), # convert no3 to ordered factor with 5 levels
                       breaks = c(-Inf, -7.5, -5.5, -3.5, -1.5, Inf),
                       labels =seq(1, 5, 1))) %>%
  mutate(no3_cat = factor(no3_cat,
                          levels = seq(1, 5, 1),
                          ordered = TRUE)) %>%
  mutate(date = as.Date(date.col)) %>%
  mutate(jdate = as.numeric(format(date, "%j"))) %>% 
  mutate(lat = map.lat.dd,
         lon = map.lon.dd) %>% # longitude
  mutate(surftemp = surftemp,
         log_surftemp = log(surftemp)) %>% 
  select(WSA9,
         state,
         size_cat,
         site.id,
         lat,
         lon,
         date,
         jdate,
         surftemp,
         log_surftemp,
         area_ha,
         log_area,
         elev,
         log_elev,
         chla,
         log_chla,
         do_surf,
         log_do,
         bf_max,
         sqrt_bf,
         n2o,
         n2o_eq,
         no3,
         no3_cat
         )

save(df_model, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda") 

nrow(df_model) # number of obs after filtering
[1] 984
print(df_model)

A second dataframe, including only the second visit observations, was constructed below. These data were later used as a “test set” to assess the out-of-sample fit of the model developed on the first-visit or training data.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/dg.rda")

# number of observations before filtering probability samples
dg %>%
  filter(!is.na(dissolved.n2o.nmol)) %>% # remove obs with missing response measurements
  nrow()
[1] 1185
df_test <- dg %>%
  filter(!is.na(dissolved.n2o.nmol)) %>%
  filter(sitetype == "PROB") %>% # probability samples only
  filter(visit.no == 2) %>%
  mutate(n2o = round(dissolved.n2o.nmol, 2),
         n2o_eq = round(sat.n2o.nmol, 2),
         n2o_sat = n2o.sat.ratio,
         n2o_em = e.n2o.nmol.d,
         n2o_flux = f.n2o.m.d,
         WSA9 = factor(ag.eco9),
         state = factor(state.abb[match(state.nm, state.name)]),
         area_ha = area.ha,
         log_area = log(area_ha),
         chla = chla.result,
         log_chla = log(chla),
         elev = elevation,
         log_elev = log(elev + 1),
         do_surf = o2.surf,
         log_do = log(do_surf),
         bf_max = max.bf,
         sqrt_bf = sqrt(bf_max),
         size_cat = recode(area.cat6, 
                           "(1,4]" = "min_4" ,
                           "(10,20]" = "10_20",
                           "(20,50]" = "20_50",
                           "(4,10]" = "4_10",
                           ">50" = "50_max")) %>%
  mutate(size_cat = factor(size_cat,
                           levels = c("min_4", "4_10", "10_20", "20_50", "50_max"),
                           ordered = TRUE)) %>%
  mutate(no3 = ifelse(nitrate.n.result <= 0.0005, 0.0005, round(nitrate.n.result, 4))) %>%# 1/2 mdl 0.01
  mutate(no3_cat = cut(log(no3), # convert no3 to ordered factor with 5 levels
                       breaks = c(-Inf, -7.5, -5.5, -3.5, -1.5, Inf),
                       labels =seq(1, 5, 1))) %>%
  mutate(no3_cat = factor(no3_cat,
                          levels = seq(1, 5, 1),
                          ordered = TRUE)) %>%
  mutate(date = as.Date(date.col)) %>%
  mutate(jdate = as.numeric(format(date, "%j"))) %>% 
  mutate(lat = map.lat.dd,
         lon = map.lon.dd) %>% # longitude
  mutate(surftemp = surftemp,
         log_surftemp = log(surftemp)) %>% 
  select(WSA9,
         state,
         size_cat,
         site.id,
         lat,
         lon,
         date,
         jdate,
         surftemp,
         log_surftemp,
         area_ha,
         log_area,
         elev,
         log_elev,
         chla,
         log_chla,
         do_surf,
         log_do,
         bf_max,
         sqrt_bf,
         n2o,
         n2o_eq,
         no3,
         no3_cat
         )

save(df_test, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_test.rda") 

nrow(df_test) # number of obs after filtering for probability samples, first visits, and removing one site missing ecoregion (WSA9) info.
[1] 95
print(df_test)

2.2 Target population

Below. the NLA sampling frame was imported and then filtered to include only the target population or sampling frame for this project.

df_pop <- read.csv(file = paste0(localPath,
              "/Environmental Protection Agency (EPA)/",
              "ORD NLA17 Dissolved Gas - Documents/",
              "inputData/NLA_Sample_Frame.csv"), header = T)

sframe <- df_pop %>%
  filter(nla17_sf != "Exclude2017") %>%
  filter(nla17_sf != "Exclude2017_Include2017NH") %>%
  filter(state != "DC") %>%
  filter(state != "HI") %>%
  droplevels() %>%
  mutate(WSA9 = factor(ag_eco9),
         WSA9 = forcats::fct_drop(WSA9), # remove NA level
         state = factor(state),
         size_cat = factor(area_cat6),
         lat = lat_dd83,
         lon = lon_dd83,
         log_area = log(area_ha),
         elev = elevation,
         log_elev = ifelse(elev <= 0, 0, elev), # assumed elev < 0 to be elev = 0
         log_elev = log(log_elev + 1)
         ) %>% 
  mutate(size_cat = recode(size_cat, 
                           "(1,4]" = "min_4" ,
                           "(10,20]" = "10_20",
                           "(20,50]" = "20_50",
                           "(4,10]" = "4_10",
                           ">50" = "50_max")) %>%
  mutate(size_cat = factor(size_cat, 
                           levels = c("min_4", "4_10", "10_20", "20_50", "50_max"),
                           ordered = TRUE)) %>%
  select(WSA9, state, size_cat, lat, lon, area_ha, log_area, elev, log_elev)

rm(df_pop)

save(sframe, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda") 

print(sframe)

The resulting target population above included a total of 465,897 waterbodies.

Cross tabulations below describe the structure of the target population with respect to the design variables. The cross-tabulation makes it clear that each ecoregion does not contain each state. Therefore, in the statistical sense, states were nested in ecoregions.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")

sframe %>%
  group_by(WSA9, state) %>%
  summarise(n = n(), .groups = "drop") %>%
  spread(state, n) %>%
  print()

Likewise, lake size category was nested in state (which was nested in ecoregion). That is, not every ecoregion:state in the population of interest contained every size category (below).

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")

sframe %>%
  group_by(WSA9, state, size_cat) %>%
  summarise(n = n(), .groups = "drop") %>%
  spread(size_cat, n) %>%
  print()

Below, the sampling frame was selected down to create a post-stratification table. Some of the variables were renamed to match the naming conventions used in the observational data above. There were 536 types of lakes in the population of interest with respect to the sampling design. The counts of those lake types (n_lakes) and their proportions relative to the total population of lakes in the sampling frame (prop_cell) are indicated below.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")

pframe <- sframe %>%
  mutate(obs = 1) %>%
  group_by(WSA9, state, size_cat) %>%
  summarise(n_lakes = sum(obs), .groups = "drop") %>%
  ungroup() %>%
  mutate(prop_cell = n_lakes/sum(n_lakes)) %>%
  mutate(type = "population") 

save(pframe, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe.rda")

print(pframe)

2.3 Sample vs. population

Below, the lake distributions in the population of interest were compared to the proportions in the observed sample. There were 352 lake types in the sample compared to the 536 in the population of of interest. In total, there were 984 observations distributed across these 352 lake types in the sample; and the number of samples was not distributed evenly across the types. Some cells were represented by as few as 1 lake. In total, 536-352 = 184 lake types in the population of interest were not represented in the sample.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

samp_props <- df_model %>%
  mutate(obs = 1) %>%
  group_by(WSA9, state, size_cat) %>%
  summarize(n_lakes = sum(obs), .groups = "drop") %>%
  ungroup() %>%
  mutate(prop_cell = round(n_lakes / sum(n_lakes), 7)) %>%
  mutate(type = "sample") 

save(samp_props, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")

print(samp_props)

Below, a graphical comparison was constructed to depict the distribution of cells in the population of interest versus those in the sample.

Another comparison between population and sample was constructed below by ecoregion. The samples were not balanced across ecoregions. Lakes in the Coastal Plains (CPL) ecoregion, for example, were clearly undersampled relative to their proportion of the population.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe.rda")

pframe_eco <- pframe %>%
  group_by(WSA9) %>%
  summarise(n_lakes = sum(n_lakes)) %>%
  ungroup() %>%
  mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
  ungroup() %>%
  mutate(type = 'population') 

save(pframe_eco, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe_eco.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")

samp_props_eco <- samp_props %>%
  group_by(WSA9) %>%
  summarise(n_lakes = sum(n_lakes)) %>%
  ungroup() %>%
  mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
  ungroup() %>%
  mutate(type = 'sample')

save(samp_props_eco, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props_eco.rda")

A similar comparison by state was constructed below.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe.rda")

pframe_state <- pframe %>%
  group_by(state) %>%
  summarise(n_lakes = sum(n_lakes)) %>%
  ungroup() %>%
  mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
  ungroup() %>%
  mutate(type = 'population')

save(pframe_state, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe_state.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")

samp_props_state <- samp_props %>%
  group_by(state) %>%
  summarise(n_lakes = sum(n_lakes)) %>%
  ungroup() %>%
  mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
  ungroup() %>%
  mutate(type = 'sample')

save(samp_props_state, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props_state.rda")

Finally, a comparison by lake size category is shown below. Note that small lakes were under-sampled relative to larger lakes by design.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe.rda")

pframe_size <- pframe %>%
  group_by(size_cat) %>%
  summarise(n_lakes = sum(n_lakes)) %>%
  ungroup() %>%
  mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
  ungroup() %>%
  mutate(type = 'population')

save(pframe_size, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/pframe_size.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props.rda")

samp_props_size <- samp_props %>%
  group_by(size_cat) %>%
  summarise(n_lakes = sum(n_lakes)) %>%
  ungroup() %>%
  mutate(prop_cell = round(n_lakes/sum(n_lakes), 7)) %>%
  ungroup() %>%
  mutate(type = 'sample')

save(samp_props_size, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/samp_props_size.rda")

2.4 Sample-based estimates

The overall mean and standard deviation for N2O in the sample:

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

df_model %>%
  summarise(mean = mean(n2o),
             sd = sd(n2o)) %>%
  print()

The same summary for equilibrium N2O:

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

df_model %>%
  summarise(mean = mean(n2o_eq),
             sd = sd(n2o_eq)) %>%
  print()

The saturation ratio (i.e., N2O / N2O-eq):

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

df_model %>%
  summarise(mean = mean(n2o / n2o_eq),
             sd = sd(n2o / n2o_eq)) %>%
  print()

Finally, roughly 67% of lakes in the sample were undersaturated (i.e., saturation ratio < 1):

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

df_model %>%
  summarise(prop_undersat = sum((n2o / n2o_eq) < 1) / 984) %>%
  print()

Using only the sample observations, a plot was constructed below of the overall mean (dashed line) along with the ecoregion-specific means (black circles). The shaded areas indicate +/- 1 standard deviation. Neither dissolved N2O nor the saturation ratio were clearly structured by ecoregion in the sample, but there did appear to be some structure in the equilibrium N2O observations.

The same summary by state is below.

Finally, the same summary by size category:

2.5 Sample data exploration

Below, the empirical distribution of N2O observations in the sample was summarized using a density and rug plot below. Note the natural log scale of the x axis. Both the N2O and equilibrium N2O data had considerable right skew even after the log transformation, which was not unexpected and has been noted in other studies (Webb et al. 2019). The saturation ratio was also skewed since it was derived from the other two observed variables (i.e., sat_ratio = n2o / n2o_eq).

Below are plots of N2O vs. NO3. The first plot shows log(N2O) vs. log(NO3), as well as the ordinal categories assigned to NO3 (vertical lines). The leftmost vertical line is dashed and separates the NO3 observations below the detection limit.

`geom_smooth()` using formula = 'y ~ x'

In the plot above, the trend is increasing and nonlinear on the log scale. The increasing variance in N2O along the NO3 gradeient suggested a potential mediator of the relationship between NO3 on N2O. Below are plots of N2O vs. NO3 for 6 quantiles of the surface temperature measurements (quantiles increasing from 1 to 6). This plot below suggested that the NO3 effect on N2O may have been stronger in lakes with higher observed temperatures.

`geom_smooth()` using formula = 'y ~ x'

The next plot below shows the relationship between N2O and NO3 at 6 different quantiles (increasing 1 to 6) of the log-scaled lake surface area estimates.

`geom_smooth()` using formula = 'y ~ x'

Similar plots are below, but with NO3 expressed as an ordered categorical variable with 5 levels. The positive and monotonic trends area similar to the previous plots where NO3 was treated as continuous. Note the large number of observations in the first NO3 category (no3_cat = 1). This category represented all of the censored observations for NO3, which was most of the data.

Below is a plot of log(N2O) vs. log(NO3) by ecoregion, which suggested that the NO3 effect on N2O may have varied by ecoregion.

`geom_smooth()` using formula = 'y ~ x'

Below is the same plot as above but for the ordered categorical version of NO3.

A plot below shows trends by state within just the Temperate Plains (TPL) ecoregion. Within states, the number of observations were relatively small, but the trends appeared closer to linear.

`geom_smooth()` using formula = 'y ~ x'

3 Model fitting

The first regression model was constructed to estimate the joint distribution of log-transformed N2O and equilibrium N2O conditional on the the design factors. Each log-transformed observation, \(i \in 1,..,N=984\), for each response, \(p \in 1:P=2\), was assumed to be drawn from a multivariate normal distribution with the parameters \(\nu\) and \(\Sigma\), where \(\nu\) is the multivariate mean estimated conditional on the design effects and \(\Sigma\) is a covariance matrix containing the observation-level variances and residual correlation: \[Y \sim MVN(\nu, \Sigma)\]

The multivariate mean is a vector of mean parameters, \(\nu:[\mu_{p=1}, \mu_{p=2}]\), for each response. Each mean is further defined by a linear combination of parameters where, for each response \(p\) and observation \(i\):

\[\mu_{pi} = \alpha_{0(pi)} + \alpha_{1(pij)} + \alpha_{2(pijk)} + \alpha_{3(pijkl)} \\ \alpha_1 \sim MVN(0, \Lambda_1) \\ \alpha_2 \sim MVN(0, \Lambda_2) \\ \alpha_3 \sim MVN(0, \Lambda_3)\]

The linear combination of parameters defining \(\mu\) above include a fixed global intercept, \(a_0\), that is estimated directly from the data, and three separate, latent group-level effects matrices, \(\alpha_1, \alpha_2, \alpha_3\). The group effects were assumed to be multivariate normal and are centered on zero in multivariate space. The spread of the effects around zero are determined by a covariance matrix, \(\Lambda_1, \Lambda_2, \text{or } \Lambda_3\), which are estimated directly from the data. These covariance terms are further defined where:

\[\Lambda = \begin{pmatrix} 1 & \tau_{p=1} \\ \tau_{p=2} & 1 \end{pmatrix} \chi \begin{pmatrix} 1 & \tau_{p=1} \\ \tau_{p=2} & 1 \end{pmatrix}\]

The \(\tau\) parameters are the group-level scale parameters, which constrain the spread of effects for each response, and \(\chi\) comprises the group-level residual correlation matrix:

\[\chi = \begin{pmatrix} 1 & \varrho \\ \varrho & 1 \end{pmatrix}\]

wherein \(\varrho\) is the group-level residual correlation between responses.

The explicit indexing in the notation above conveys the relationship between the parameters and each observation, \(i\), and emphasizes the nested structure of the observations within the group effects. Specifically, every observation, \(i\), was nested in a lake size category, \(l\), which was nested in a state, \(k\), and ecoregion, \(j\). The parameter \(\alpha_1\), therefore, accounted for ecoregion-scale group effects or deviations from the global mean; \(\alpha_2\) accounted for state-level group effects nested in ecoregions; and \(\alpha_3\) accounted for lake size group effects within states and ecoregions.

Finally, the observation-level covariance term, \(\Sigma\), was parameterized as: \[\Sigma = \begin{pmatrix} 1 & \sigma_{p=1} \\ \sigma_{p=2} & 1 \end{pmatrix} \Omega \begin{pmatrix} 1 & \sigma_{p=1} \\ \sigma_{p=2} & 1 \end{pmatrix}\]

wherein the \(\sigma\) parameters are the observation-level standard deviations for each response and \(\Omega\) comprises the observation-level residual correlation matrix: \[\Omega = \begin{pmatrix} 1 & \rho \\ \rho & 1 \end{pmatrix}\] wherein \(\rho\) is the residual correlation between responses.

For model fitting, priors were needed for all parameters conditioned directly on the data, which included the global intercept, the scale parameters, and the correlation matrices. A normal or Gaussian prior, \(N(\mu = 2, \sigma = 1)\) centered near the (log-scale) data means, was used for the global intercept parameter for each response. This prior was considered minimally informative as it placed most (~80%) of the prior mass over values between approximately 2 and 27 ng/L for median N2O or N2O equilibrium concentration and included support in the tails for values approaching 0 ng/L on the lower end and 80 ng/L on the high end. We placed \(Exp(2)\) priors over all scale parameters, which placed most of the support between values very close to 0 and values near 1 (central 80% density interval from approximately 0.005 to 1.15). Finally, for the correlation matrices, an \(LKJ(\eta =2)\) prior was used, which, for a 2-dimensional response, placed most support for correlations between approximately -0.9 and 0.9. This prior seemed reasonable as there was no clear causal mechanisms that were thought to ensure a strong direct correlation between the N2O measures. Any potential residual dependence was expected to be indirect due to, for example, a common causal factor (e.g., elevation, temperature). For more information on prior choice recommendations in Stan, see: https://github.com/stan-dev/stan/wiki/Prior-Choice-Recommendations

The \(\textbf{brms}\) package (Bürkner 2017) for \(\textbf{R}\) (R Core Team 2021) was used to fit all of the models in a fully Bayesian setting. The formula syntax of the \(\textbf{brms}\) package is similar to the syntax used in the \(\textbf{lme4}\) package that is widely used to fit mixed effects models in frequentist settings In either package, the linear predictor for \(\mu\) described above could be expressed as:

\[\sim 1 + (1|WSA9) + (1|WSA9:state) + (1|WSA9:state:size)\]

In the \(\textbf{brms}\) package, there is additionaly functionality and syntax for multivariate responses and for allowing the varying intercepts in a multivariate model to be correlated, e.g.,:

\[ N_2O_{dissolved}\sim 1 + (1|a|WSA9) + (1|b|WSA9:state) + (1|c|WSA9:state:size) \\ N_2O_{equilibrium}\sim 1 + (1|a|WSA9) + (1|b|WSA9:state) + (1|c|WSA9:state:size)\]

The above syntax would indicate that the linear predictor for both responses in the multivariate model have the same group-level varying effects, and that each of those effects are allowed to be correlated between responses.

For the remainder of this document, only this simplified syntax is presented to describe the model parameterizations. For more information on \(\textbf{brms}\) functionality and syntax with multivariate response models, the package vignette may be helpful, and can be found at: https://cran.r-project.org/web/packages/brms/vignettes/brms_multivariate.html.

3.1 Model 1

The first model fit was the one described above.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

bf_n2o <- bf(log(n2o) ~ 1 + 
               (1 | a | WSA9) + 
               (1 | b | WSA9:state) + 
               (1 | c | WSA9:state:size_cat),
             family = gaussian())

bf_n2oeq <- bf(log(n2o_eq) ~ 1 + 
               (1 | a | WSA9) + 
               (1 | b | WSA9:state) +
               (1 | c | WSA9:state:size_cat),
             family = gaussian())

priors <- c(
  prior(normal(2, 1), class = "Intercept", resp = "logn2o"), # centered near data mean
  prior(exponential(2), class = "sd", resp = "logn2o"),
  prior(exponential(2), class = "sigma", resp = "logn2o"),
  prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"), # centered near data mean
  prior(exponential(2), class = "sd", resp = "logn2oeq"),
  prior(exponential(2), class = "sigma", resp = "logn2oeq"),
  prior(lkj(2), class = "rescor"),
  prior(lkj(2), class = "cor")
  )

n2o_mod1 <- brm(bf_n2o + bf_n2oeq + set_rescor(rescor = TRUE),
                data = df_model,
                prior = priors,
                control = list(adapt_delta = 0.99, max_treedepth = 14),
                #sample_prior = "only",
                save_pars = save_pars(all = TRUE),
                seed = 145,
                chains=4, 
                iter=5000, 
                cores=4)

save(n2o_mod1, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod1.rda")

3.1.1 Summarize fit

The summaries of the estimated parameters and key HMC convergence diagnostics for the fitted model are printed below. There were no obvious issues with the HMC sampling. All \(\hat{R}\) values were less than 1.01 and effective sample size (\(ESS\)) calculations suggested that the posterior contained a sufficient number of effective samples for conducting inference.

 Family: MV(gaussian, gaussian) 
  Links: mu = identity; sigma = identity
         mu = identity; sigma = identity 
Formula: log(n2o) ~ 1 + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         log(n2o_eq) ~ 1 + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
   Data: df_model (Number of observations: 984) 
  Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
         total post-warmup draws = 10000

Priors: 
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2oeq ~ normal(2, 1)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sigma_logn2o ~ exponential(2)
<lower=0> sigma_logn2oeq ~ exponential(2)

Group-Level Effects: 
~WSA9 (Number of levels: 9) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.04      0.03     0.00     0.13 1.00
sd(logn2oeq_Intercept)                       0.06      0.02     0.03     0.11 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)     0.05      0.44    -0.80     0.83 1.01
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         2475     4230
sd(logn2oeq_Intercept)                       3326     5332
cor(logn2o_Intercept,logn2oeq_Intercept)     1141     3129

~WSA9:state (Number of levels: 96) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.26      0.03     0.21     0.32 1.00
sd(logn2oeq_Intercept)                       0.04      0.01     0.03     0.05 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)     0.24      0.15    -0.07     0.52 1.00
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         3199     4775
sd(logn2oeq_Intercept)                       3549     5476
cor(logn2o_Intercept,logn2oeq_Intercept)     3332     5553

~WSA9:state:size_cat (Number of levels: 352) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.09      0.04     0.01     0.16 1.00
sd(logn2oeq_Intercept)                       0.02      0.01     0.00     0.03 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)    -0.22      0.37    -0.85     0.58 1.00
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                          863     1397
sd(logn2oeq_Intercept)                        928     1365
cor(logn2o_Intercept,logn2oeq_Intercept)     1661     2807

Population-Level Effects: 
                   Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_Intercept       2.02      0.04     1.95     2.09 1.00     2641     3963
logn2oeq_Intercept     2.00      0.02     1.96     2.04 1.00     3446     4550

Family Specific Parameters: 
               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma_logn2o       0.40      0.01     0.37     0.42 1.00     2749     5523
sigma_logn2oeq     0.08      0.00     0.08     0.09 1.00     4790     6698

Residual Correlations: 
                        Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq)     0.21      0.04     0.14     0.27 1.00     6172     7243

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

In the summary above, the estimated standard deviations for the varying group effects on the mean behavior of the dissolved N2O response suggested fairly low, but non-zero variability across each of the three levels. The standard deviations estimated for the same varying effects for equilibrium N2O were also relatively small. Finally, note the relatively small, but positive residual correlation between the two N2O responses.

Before investing too much into the interpretation of this model, however, the model fit was evaluated below using a series of graphical posterior predictive checks [PPC; Gelman et al. (2014); Gelman, Hill, and Vehtari (2020), Ch. 11].

3.1.2 Model checks

3.1.2.1 Dissolved N2O

Below are a series of panels illustrating graphical PPCs for the log(N2O) component of the model. The top left panel compares a density plot of the observed data (black line) to density lines drawn for 200 samples from the posterior predictive distribution (PPD; blue lines) of the fitted model. The top right panel similarly compares the cumulative density distributions. The left middle panel simulataneously compares means vs. standard deviations for 1000 draws from the PPD (blue dots) to the sample mean and standard deviation (black dot). The right middle panel compares skewness vs. kurtosis for 1000 draws from the PPD to the skewness and kurtosis values calculated for the observed data. The bottom left panel compares max vs. min values for 1000 draws from the PPD to the max and min values of the sample data. Finally, the bottom right panel shows the observed vs. average predicted values for each observation in the sample. The average predicted values were calculated as the mean prediction for each observation in the PPD based on 1000 draws.

The general takeaway from the PPCs above was that the model replicated the central tendency of the observed data fairly well, but failed to sufficiently replicate other important aspects of the distribution, such as skewness and kurtosis. The observed vs. average predictions scatterplot suggested substantial heteroscedasticity in the errors.

The same checks were run below, but for the test set of 95 held-out, second-visit data points.

The patterns in misfit indicated above for the re-visit data were similar to the patterns indicated in the PPCs with the training data.

3.1.2.2 Equilibrium N2O

Below are PPCs for the equilibrium N2O component of the model. As with the dissolved N2O response above, the model did an OK job at replicating the central tendency, but performed less well at replicating some important aspects of the overall distribution.

Below are the same PPCs for equilibrium N2O in the re-visit sites.

3.1.2.3 Bivariate

The graphical check below compares bivariate density contours estimated from the observed data (black lines) to density contours estimated for each of 20 draws from the PPD. The model appeared to do a good job of replicating the bivariate mean, but was poor at representing the overall joint distribution.

The same bivariate check is shown below for the re-visit data.

3.1.2.4 Saturation

The graphical PPCs below were aimed at evaluating how well the multivariate model did at representing the observed saturation ratio: \[N_2O_{dissolved}:N_2O_{equilibrium}\] This quantity was estimated as a derived variable by simply dividing the N2O PPD by the equilibrium N2O PPD. Likewise, the proportion of under-saturated lakes in the sample was estimated by summing the number of lakes from each posterior predictive draw wherein the ratio was < 1 and dividing that number by the total number of lakes in the sample, which was 984. Overall, these checks indicated that properly representing the tails of the N2O and N2O-eq observations would likely be necessary in order to better replicate the observed saturation metrics. For example, the model did a poor job replicating the observed proportion of under-saturated lakes, underestimating it by more than 10 percentage points, on average.

The top left panel, above, is a density plot of the observed saturation ratio (black line) compared to an estimate using 50 draws from the model (blue lines). The top right panel shows the observed proportion of under-saturated lakes compared to a model estimate based on 1000 draws from the PPD. The left middle panel shows the mean vs. standard deviation of the saturation ratio for the observed data compared to the same estimates for 500 posterior draws from the model’s PPD. The right middle panel shows the max vs. min for the sample compared to 500 draws from the model’s PPD. Finally, the bottom left panel shows the observed vs. average predicted saturation ratio for all 984 lakes sampled in the dataset.

The same PPCs are show below for the revisit data.

The checks above indicated that the model did a similarly underwhelming job of replicating some key properties of the saturation metrics calculated from the re-visit data.

3.1.2.5 R-square

Below, the Bayesian \(R^2\) values are reported for each reasponse in the model.

         Estimate Est.Error  Q2.5 Q97.5
R2logn2o    0.247     0.031 0.187 0.309
           Estimate Est.Error  Q2.5 Q97.5
R2logn2oeq    0.377     0.025 0.328 0.425

The \(R^2\) were also estimated for the re-visit data.

         Estimate Est.Error  Q2.5 Q97.5
R2logn2o    0.413      0.04 0.331 0.489
           Estimate Est.Error  Q2.5 Q97.5
R2logn2oeq    0.322     0.026 0.271 0.374

3.2 Model 2

In an attempt to better fit the observed data, the next model included distributional sub-models to allow for heterogeneous variances for each response conditional on the survey design structure.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

bf_n2o <- bf(log(n2o) ~ 1 +
               (1 | a | WSA9) + 
               (1 | b | WSA9:state) + 
               (1 | c | WSA9:state:size_cat),
             sigma ~ 1 +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat), 
             family = gaussian())

bf_n2oeq <- bf(log(n2o_eq) ~ 1 +
                 (1 | a | WSA9) + 
                 (1 | b | WSA9:state) +
                 (1 | c | WSA9:state:size_cat),
             sigma ~ 1 +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat),
             family = gaussian())

priors <- c(
  prior(normal(2, 1), class = "Intercept", resp = "logn2o"),
  prior(exponential(2), class = "sd", resp = "logn2o"),
  prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2o"),
  prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2o"),
  prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"), 
  prior(exponential(2), class = "sd", resp = "logn2oeq"),
  prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2oeq"),
  prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2oeq"),
  
  prior(lkj(2), class = "rescor"),
  prior(lkj(2), class = "cor")
  )

n2o_mod2 <- brm(bf_n2o + bf_n2oeq + set_rescor(rescor = TRUE),
                data = df_model, 
                prior = priors,
  control = list(adapt_delta = 0.975, max_treedepth = 12),
  #sample_prior = "only",
  save_pars = save_pars(all = TRUE),
  seed = 84512,
  chains=4, 
  iter=5000, 
  cores=4)

save(n2o_mod2, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod2.rda")

3.2.1 Summarize fit

The summaries of the estimated parameters and key HMC convergence diagnostics for the fitted model are printed below.

 Family: MV(gaussian, gaussian) 
  Links: mu = identity; sigma = log
         mu = identity; sigma = log 
Formula: log(n2o) ~ 1 + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         sigma ~ 1 + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
         log(n2o_eq) ~ 1 + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         sigma ~ 1 + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
   Data: df_model (Number of observations: 984) 
  Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
         total post-warmup draws = 10000

Priors: 
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2o_sigma ~ normal(-1, 2)
Intercept_logn2oeq ~ normal(2, 1)
Intercept_logn2oeq_sigma ~ normal(-1, 2)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2o_sigma ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sd_logn2oeq_sigma ~ exponential(2)

Group-Level Effects: 
~WSA9 (Number of levels: 9) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.06      0.03     0.02     0.12 1.00
sd(logn2oeq_Intercept)                       0.05      0.02     0.03     0.09 1.00
sd(sigma_logn2o_Intercept)                   0.22      0.12     0.02     0.50 1.00
sd(sigma_logn2oeq_Intercept)                 0.16      0.08     0.04     0.34 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)     0.57      0.30    -0.18     0.95 1.00
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         2247     1772
sd(logn2oeq_Intercept)                       3423     4761
sd(sigma_logn2o_Intercept)                   1892     3094
sd(sigma_logn2oeq_Intercept)                 2413     1991
cor(logn2o_Intercept,logn2oeq_Intercept)     2696     3538

~WSA9:state (Number of levels: 96) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.08      0.02     0.04     0.11 1.00
sd(logn2oeq_Intercept)                       0.04      0.01     0.03     0.05 1.00
sd(sigma_logn2o_Intercept)                   0.56      0.08     0.40     0.74 1.00
sd(sigma_logn2oeq_Intercept)                 0.22      0.05     0.11     0.32 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)     0.42      0.19    -0.00     0.74 1.00
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         1276     1733
sd(logn2oeq_Intercept)                       2695     5090
sd(sigma_logn2o_Intercept)                   2007     3462
sd(sigma_logn2oeq_Intercept)                 1851     1881
cor(logn2o_Intercept,logn2oeq_Intercept)     1076     1960

~WSA9:state:size_cat (Number of levels: 352) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.06      0.01     0.03     0.09 1.00
sd(logn2oeq_Intercept)                       0.02      0.01     0.00     0.03 1.00
sd(sigma_logn2o_Intercept)                   0.61      0.05     0.51     0.72 1.00
sd(sigma_logn2oeq_Intercept)                 0.19      0.06     0.07     0.29 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)    -0.00      0.34    -0.70     0.62 1.00
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         1329     2182
sd(logn2oeq_Intercept)                       1052     1452
sd(sigma_logn2o_Intercept)                   2622     4939
sd(sigma_logn2oeq_Intercept)                 1603     1725
cor(logn2o_Intercept,logn2oeq_Intercept)      996     2063

Population-Level Effects: 
                         Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_Intercept             1.93      0.03     1.88     1.99 1.00     3338     4462
sigma_logn2o_Intercept      -1.40      0.12    -1.63    -1.17 1.00     3511     5077
logn2oeq_Intercept           2.00      0.02     1.96     2.03 1.00     3384     4145
sigma_logn2oeq_Intercept    -2.60      0.07    -2.75    -2.45 1.00     4004     4848

Residual Correlations: 
                        Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq)     0.36      0.03     0.29     0.43 1.00     6474     7733

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

From the summary above, note the moderate and positive residual correlation between the two N2O responses. The estimated standard deviations for the varying group effects on the mean behavior of the dissolved N2O response suggested fairly low, but non-zero variability across each of the three levels. The standard deviations estimated for the same varying effects for equilibrium N2O were also relatively small. However, before investing too much into the interpretation of these results, the model fit was further evaluated below using a series of graphical posterior predictive checks (PPCs).

3.2.2 Model checks

Below the same PPCs were performed as with the initial model (see above for more details on each panel). ##### Dissolved N2O Though the checks below suggest some improvement in replicating the tails of the observed data, this model did a poorer job at replicating central tendency.

3.2.2.1 Equilibrium N2O

The checks below suggest this model offered no improvement upon the initial model for equilibrium N2O. This model also appeared to do a poorer job of replicating the mean and overall standard deviation compared to the initial model.

3.2.2.2 Bivariate

This check perhaps suggested an improvement with regard to replicating the joint density. However, the predictions were still clearly over-dispersed relative to the observations.

3.2.2.3 Saturation

The PPCs for the saturation metrics below indicated that including the distributional models was perhaps an improvement on the initial model in some aspects; in particular, the bias in the predicted proportion of under-saturated lakes was substantially decreased. However, there appeared to still be issues in replicating the tails as well as issues with central tendency.

3.2.2.4 R-square

Relative to model 1, there was a substantial decrease in the \(R^2\) estimate for the dissolved N2O component of this model. The estimate for the equilibrium N2O-eq component was similar to the model 1.

         Estimate Est.Error  Q2.5 Q97.5
R2logn2o    0.056     0.009 0.038 0.075
           Estimate Est.Error  Q2.5 Q97.5
R2logn2oeq    0.379     0.022 0.335 0.421

3.3 Model 3

In the next model, we used covariates to try to improve the fit. The categorical version of the NO3 covariate was used as a monotonic ordinal predictor in the dissolved N2O component of the modl. For the equlibrium N2O component, we included surface temperature and log-transformed elevation, along with their interaction. The models also retained the distributional specifications included in model 2 above.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

bf_n2o <- bf(log(n2o) ~ mo(no3_cat) +
               surftemp +
               (mo(no3_cat) | a | WSA9) + 
               (mo(no3_cat) | b | WSA9:state) + 
               (1 | c | WSA9:state:size_cat),
             sigma ~ 1 +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat), 
             family = gaussian())

bf_n2oeq <- bf(log(n2o_eq) ~ surftemp +
                 log_elev +
                 surftemp:log_elev +
                 (1 | a | WSA9) + 
                 (1 | b | WSA9:state) +
                 (1 | c | WSA9:state:size_cat),
             sigma ~ 1 +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat),
             family = gaussian())

priors <- c(
  prior(normal(2, 1), class = "Intercept", resp = "logn2o"),
  prior(normal(0, 1), class = "b", resp = "logn2o"),
  prior(exponential(2), class = "sd", resp = "logn2o"),
  prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2o"),
  prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2o"),
  prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"), 
  prior(normal(0, 1), class = "b", resp = "logn2oeq"), 
  prior(exponential(2), class = "sd", resp = "logn2oeq"), 
  prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2oeq"),
  prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2oeq"),
  
  prior(lkj(2), class = "rescor"),
  prior(lkj(2), class = "cor")
  )

n2o_mod3 <- brm(bf_n2o + bf_n2oeq + set_rescor(rescor = TRUE),
                data = df_model, 
                prior = priors,
  control = list(adapt_delta = 0.975, max_treedepth = 12),
  #sample_prior = "only",
  save_pars = save_pars(all = TRUE),
  seed = 98456,
  chains=4, 
  iter=5000, 
  cores=4)

save(n2o_mod3, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod3.rda")

3.3.1 Summarize fit

The fitted parameters and MCMC diagnostics are below.

 Family: MV(gaussian, gaussian) 
  Links: mu = identity; sigma = log
         mu = identity; sigma = log 
Formula: log(n2o) ~ mo(no3_cat) + surftemp + (mo(no3_cat) | a | WSA9) + (mo(no3_cat) | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         sigma ~ 1 + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
         log(n2o_eq) ~ surftemp + log_elev + surftemp:log_elev + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         sigma ~ 1 + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
   Data: df_model (Number of observations: 984) 
  Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
         total post-warmup draws = 10000

Priors: 
b_logn2o ~ normal(0, 1)
b_logn2oeq ~ normal(0, 1)
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2o_sigma ~ normal(-1, 2)
Intercept_logn2oeq ~ normal(2, 1)
Intercept_logn2oeq_sigma ~ normal(-1, 2)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2o_sigma ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sd_logn2oeq_sigma ~ exponential(2)
simo_logn2o_mono3_cat1 ~ dirichlet(1)

Group-Level Effects: 
~WSA9 (Number of levels: 9) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.05      0.02     0.02     0.10 1.00
sd(logn2o_mono3_cat)                         0.14      0.05     0.06     0.26 1.00
sd(logn2oeq_Intercept)                       0.04      0.01     0.02     0.07 1.00
sd(sigma_logn2o_Intercept)                   0.12      0.08     0.01     0.31 1.00
sd(sigma_logn2oeq_Intercept)                 0.36      0.11     0.19     0.64 1.00
cor(logn2o_Intercept,logn2o_mono3_cat)      -0.14      0.33    -0.72     0.53 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)     0.36      0.29    -0.28     0.83 1.00
cor(logn2o_mono3_cat,logn2oeq_Intercept)     0.37      0.29    -0.26     0.82 1.00
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         4265     3917
sd(logn2o_mono3_cat)                         4747     5482
sd(logn2oeq_Intercept)                       4798     5704
sd(sigma_logn2o_Intercept)                   3419     4599
sd(sigma_logn2oeq_Intercept)                 5027     6638
cor(logn2o_Intercept,logn2o_mono3_cat)       4970     6018
cor(logn2o_Intercept,logn2oeq_Intercept)     5073     6636
cor(logn2o_mono3_cat,logn2oeq_Intercept)     7256     7538

~WSA9:state (Number of levels: 96) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.03      0.02     0.00     0.07 1.00
sd(logn2o_mono3_cat)                         0.14      0.02     0.10     0.18 1.00
sd(logn2oeq_Intercept)                       0.03      0.00     0.03     0.04 1.00
sd(sigma_logn2o_Intercept)                   0.30      0.09     0.09     0.47 1.00
sd(sigma_logn2oeq_Intercept)                 0.28      0.06     0.17     0.40 1.00
cor(logn2o_Intercept,logn2o_mono3_cat)      -0.30      0.32    -0.82     0.45 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)     0.00      0.27    -0.53     0.55 1.01
cor(logn2o_mono3_cat,logn2oeq_Intercept)     0.45      0.13     0.16     0.69 1.00
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                          894     2100
sd(logn2o_mono3_cat)                         3795     5396
sd(logn2oeq_Intercept)                       4164     5957
sd(sigma_logn2o_Intercept)                   1157     1279
sd(sigma_logn2oeq_Intercept)                 2747     4313
cor(logn2o_Intercept,logn2o_mono3_cat)        550      693
cor(logn2o_Intercept,logn2oeq_Intercept)      596      971
cor(logn2o_mono3_cat,logn2oeq_Intercept)     2536     4431

~WSA9:state:size_cat (Number of levels: 352) 
                                         Estimate Est.Error l-95% CI u-95% CI Rhat
sd(logn2o_Intercept)                         0.06      0.01     0.04     0.08 1.00
sd(logn2oeq_Intercept)                       0.00      0.00     0.00     0.01 1.00
sd(sigma_logn2o_Intercept)                   0.58      0.06     0.47     0.70 1.00
sd(sigma_logn2oeq_Intercept)                 0.28      0.05     0.18     0.39 1.00
cor(logn2o_Intercept,logn2oeq_Intercept)     0.26      0.39    -0.60     0.87 1.00
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         1429     2386
sd(logn2oeq_Intercept)                       1779     3895
sd(sigma_logn2o_Intercept)                   2003     4421
sd(sigma_logn2oeq_Intercept)                 1812     3745
cor(logn2o_Intercept,logn2oeq_Intercept)     4523     5554

Population-Level Effects: 
                           Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_Intercept               2.40      0.05     2.29     2.50 1.00     5046     6296
sigma_logn2o_Intercept        -1.70      0.08    -1.87    -1.55 1.00     5162     5452
logn2oeq_Intercept             3.10      0.05     3.01     3.19 1.00     8903     7808
sigma_logn2oeq_Intercept      -3.54      0.14    -3.81    -3.27 1.00     4065     5338
logn2o_surftemp               -0.02      0.00    -0.03    -0.02 1.00     5529     6684
logn2oeq_surftemp             -0.04      0.00    -0.04    -0.04 1.00     9722     7658
logn2oeq_log_elev             -0.07      0.01    -0.09    -0.06 1.00     9200     7505
logn2oeq_surftemp:log_elev     0.00      0.00     0.00     0.00 1.00     9527     8028
logn2o_mono3_cat               0.23      0.05     0.12     0.34 1.00     3948     4777

Simplex Parameters: 
                     Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
logn2o_mono3_cat1[1]     0.02      0.01     0.00     0.04 1.00     5535     5409
logn2o_mono3_cat1[2]     0.09      0.02     0.04     0.13 1.00     4281     5251
logn2o_mono3_cat1[3]     0.21      0.05     0.13     0.32 1.00     3683     4649
logn2o_mono3_cat1[4]     0.69      0.05     0.58     0.77 1.00     3498     4251

Residual Correlations: 
                        Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq)     0.15      0.04     0.07     0.23 1.00    11381     7610

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

3.3.2 Model checks

3.3.2.1 Dissolved N2O

The PPCs below indicated a better fit compared to the previous models. The central tendency and tail behavior looked to be reasonably replicated by comparison. However, the observed vs. predicted plot suggested that larger overserved values were being systematically underestimated.

3.3.2.2 Equilibrium N2O

The PPCs below indicated that this model appeared to be an improvement for equilibrium N2O as well. However, some checks (e.g., skewness) suggested some room for additional improvement.

3.3.2.3 Bivariate

The check for the joint distribution below also suggested an improvement up the previous models.

3.3.2.4 Saturation

This model looked to be an improvement with regard to the PPCs for the saturation metrics. However, the proportion of under-saturated lakes remained biased low and other checks indicated that further improvements would be ideal.

3.3.2.5 R-square

The \(R^2\) estimates for this model are below and suggested substantial improvements on the previous models.

         Estimate Est.Error  Q2.5 Q97.5
R2logn2o    0.626     0.017 0.591  0.66
           Estimate Est.Error Q2.5 Q97.5
R2logn2oeq    0.879     0.004 0.87 0.886

3.3.3 Covariate effects

Below are plots illustrating the modeled effects of covariates on both N2O and equilibrium N2O. #### N2O The conditional effects plots below for N2O illustrate a positive, monotonic, and non-linear relationship between NO3 and N2O; and a negative, linear relationship between surface temperature and N2O.

3.3.3.1 Equilibrium N2O

The modeled effects below for the equilibrium N2O component of the model illustrated a negative relationship between equilibrium N2O and both predictors and an interaction such that the surface temperature effect became slightly steeper at lower elevations.

3.4 Model 4

In the next model, covariate terms were also included in the \(\sigma\) components of both models in order to try to better capture remaining heterogeneity in the variances of both N2O and N2O-eq.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

bf_n2o <- bf(log(n2o) ~ mo(no3_cat) +
               surftemp +
               (mo(no3_cat) | a | WSA9) + 
               (mo(no3_cat) | b | WSA9:state) + 
               (1 | c | WSA9:state:size_cat),
             sigma ~ mo(no3_cat) +
               surftemp +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat), 
             family = gaussian())

bf_n2oeq <- bf(log(n2o_eq) ~ surftemp +
                 log_elev +
                 surftemp:log_elev +
                 (1 | a | WSA9) + 
                 (1 | b | WSA9:state) +
                 (1 | c | WSA9:state:size_cat),
             sigma ~ surftemp +
               log_elev +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat),
             family = gaussian())

priors <- c(
  prior(normal(2, 1), class = "Intercept", resp = "logn2o"),
  prior(normal(0, 1), class = "b", resp = "logn2o"),
  prior(exponential(2), class = "sd", resp = "logn2o"),
  prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2o"),
  prior(normal(0, 1), class = "b", dpar = "sigma", resp = "logn2o"),
  prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2o"),
  prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"), 
  prior(normal(0, 1), class = "b", resp = "logn2oeq"), 
  prior(exponential(2), class = "sd", resp = "logn2oeq"), 
  prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2oeq"),
  prior(normal(0, 1), class = "b", dpar = "sigma", resp = "logn2oeq"),
  prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2oeq"),
  
  prior(lkj(2), class = "rescor"),
  prior(lkj(2), class = "cor")
  )

n2o_mod4 <- brm(bf_n2o + bf_n2oeq + set_rescor(rescor = TRUE),
                data = df_model, 
                prior = priors,
  control = list(adapt_delta = 0.975, max_treedepth = 12),
  #sample_prior = "only",
  save_pars = save_pars(all = TRUE),
  seed = 15851,
  chains=4, 
  iter=5000, 
  cores=4)

save(n2o_mod4, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod4.rda")

3.4.1 Summarize fit

Below is a summary of the fitted parameters along with some convergence diagnostics.

 Family: MV(gaussian, gaussian) 
  Links: mu = identity; sigma = log
         mu = identity; sigma = log 
Formula: log(n2o) ~ mo(no3_cat) + surftemp + (mo(no3_cat) | a | WSA9) + (mo(no3_cat) | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         sigma ~ mo(no3_cat) + surftemp + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
         log(n2o_eq) ~ surftemp + log_elev + surftemp:log_elev + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         sigma ~ surftemp + log_elev + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
   Data: df_model (Number of observations: 984) 
  Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
         total post-warmup draws = 10000

Priors: 
b_logn2o ~ normal(0, 1)
b_logn2o_sigma ~ normal(0, 1)
b_logn2oeq ~ normal(0, 1)
b_logn2oeq_sigma ~ normal(0, 1)
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2o_sigma ~ normal(-1, 2)
Intercept_logn2oeq ~ normal(2, 1)
Intercept_logn2oeq_sigma ~ normal(-1, 2)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2o_sigma ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sd_logn2oeq_sigma ~ exponential(2)
simo_logn2o_mono3_cat1 ~ dirichlet(1)
simo_logn2o_sigma_mono3_cat1 ~ dirichlet(1)

Group-Level Effects: 
~WSA9 (Number of levels: 9) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(logn2o_Intercept)                        0.050     0.020    0.020    0.100 1.000
sd(logn2o_mono3_cat)                        0.145     0.054    0.065    0.272 1.000
sd(logn2oeq_Intercept)                      0.036     0.012    0.019    0.065 1.001
sd(sigma_logn2o_Intercept)                  0.113     0.080    0.005    0.303 1.001
sd(sigma_logn2oeq_Intercept)                0.208     0.098    0.039    0.435 1.001
cor(logn2o_Intercept,logn2o_mono3_cat)     -0.186     0.327   -0.755    0.489 1.000
cor(logn2o_Intercept,logn2oeq_Intercept)    0.344     0.290   -0.277    0.817 1.000
cor(logn2o_mono3_cat,logn2oeq_Intercept)    0.364     0.286   -0.269    0.819 1.001
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         4733     4348
sd(logn2o_mono3_cat)                         4386     6208
sd(logn2oeq_Intercept)                       3977     5215
sd(sigma_logn2o_Intercept)                   2543     4693
sd(sigma_logn2oeq_Intercept)                 2777     2177
cor(logn2o_Intercept,logn2o_mono3_cat)       4616     6092
cor(logn2o_Intercept,logn2oeq_Intercept)     5667     6074
cor(logn2o_mono3_cat,logn2oeq_Intercept)     7634     7624

~WSA9:state (Number of levels: 96) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(logn2o_Intercept)                        0.035     0.017    0.003    0.068 1.001
sd(logn2o_mono3_cat)                        0.117     0.022    0.076    0.162 1.001
sd(logn2oeq_Intercept)                      0.033     0.003    0.027    0.040 1.000
sd(sigma_logn2o_Intercept)                  0.181     0.099    0.011    0.374 1.004
sd(sigma_logn2oeq_Intercept)                0.287     0.057    0.177    0.403 1.001
cor(logn2o_Intercept,logn2o_mono3_cat)     -0.317     0.311   -0.810    0.405 1.003
cor(logn2o_Intercept,logn2oeq_Intercept)    0.025     0.265   -0.497    0.557 1.005
cor(logn2o_mono3_cat,logn2oeq_Intercept)    0.448     0.165    0.098    0.738 1.001
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                          981     2017
sd(logn2o_mono3_cat)                         3149     4612
sd(logn2oeq_Intercept)                       3457     6360
sd(sigma_logn2o_Intercept)                    858     2373
sd(sigma_logn2oeq_Intercept)                 2470     3862
cor(logn2o_Intercept,logn2o_mono3_cat)        945     1286
cor(logn2o_Intercept,logn2oeq_Intercept)      556      823
cor(logn2o_mono3_cat,logn2oeq_Intercept)     1518     3021

~WSA9:state:size_cat (Number of levels: 352) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(logn2o_Intercept)                        0.065     0.011    0.042    0.087 1.003
sd(logn2oeq_Intercept)                      0.004     0.002    0.000    0.008 1.001
sd(sigma_logn2o_Intercept)                  0.539     0.055    0.432    0.647 1.002
sd(sigma_logn2oeq_Intercept)                0.263     0.051    0.162    0.363 1.001
cor(logn2o_Intercept,logn2oeq_Intercept)    0.395     0.348   -0.479    0.904 1.001
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         1478     2832
sd(logn2oeq_Intercept)                       1506     2453
sd(sigma_logn2o_Intercept)                   1443     3611
sd(sigma_logn2oeq_Intercept)                 2372     4366
cor(logn2o_Intercept,logn2oeq_Intercept)     4231     4956

Population-Level Effects: 
                           Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS Tail_ESS
logn2o_Intercept              2.386     0.055    2.278    2.490 1.000     5971     7057
sigma_logn2o_Intercept       -1.855     0.281   -2.389   -1.294 1.000     5965     7704
logn2oeq_Intercept            3.115     0.051    3.016    3.217 1.001     7109     7366
sigma_logn2oeq_Intercept     -1.922     0.373   -2.634   -1.180 1.000     8445     7581
logn2o_surftemp              -0.021     0.002   -0.026   -0.017 1.000     5850     7677
sigma_logn2o_surftemp        -0.001     0.011   -0.023    0.021 1.001     6175     7768
logn2oeq_surftemp            -0.042     0.002   -0.046   -0.039 1.001     8285     7516
logn2oeq_log_elev            -0.080     0.008   -0.096   -0.065 1.001     7656     7564
logn2oeq_surftemp:log_elev    0.002     0.000    0.002    0.003 1.000     8407     7502
sigma_logn2oeq_surftemp      -0.065     0.010   -0.085   -0.046 1.000    10043     8163
sigma_logn2oeq_log_elev      -0.019     0.038   -0.095    0.054 1.000     6646     7910
logn2o_mono3_cat              0.225     0.058    0.108    0.340 1.000     4488     5143
sigma_logn2o_mono3_cat        0.256     0.037    0.187    0.331 1.000     6036     7643

Simplex Parameters: 
                           Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS Tail_ESS
logn2o_mono3_cat1[1]          0.018     0.012    0.001    0.045 1.000     5709     4429
logn2o_mono3_cat1[2]          0.093     0.027    0.041    0.149 1.000     5034     5645
logn2o_mono3_cat1[3]          0.231     0.060    0.126    0.366 1.000     4974     5478
logn2o_mono3_cat1[4]          0.659     0.062    0.520    0.763 1.000     4446     5210
sigma_logn2o_mono3_cat1[1]    0.107     0.066    0.007    0.255 1.000     6168     4471
sigma_logn2o_mono3_cat1[2]    0.129     0.087    0.006    0.328 1.000     8105     5010
sigma_logn2o_mono3_cat1[3]    0.459     0.151    0.168    0.758 1.000     7272     5802
sigma_logn2o_mono3_cat1[4]    0.304     0.139    0.038    0.569 1.000     6289     4264

Residual Correlations: 
                        Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq)    0.146     0.040    0.067    0.223 1.001     9839     8508

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

3.4.2 Model checks

Again, the same PPCs were employed for this model as above. #### Dissolved N2O Again, this model appeared to be an improvement on the previous model, particularly with regard to the more constant variance indicated in the observed vs. predicted plot (bottom, right panel).

Using all posterior draws for ppc type 'scatter_avg' by default.

3.4.2.1 Equilibrium N2O

This component of the model also seemed to be an improvement over model 3, with better representation in the tails as indicated in the skewness vs. kurtosis PPC.

3.4.2.2 Bivariate

Again, an improvement over the previous model with a tighter fit of the PPC to the observed bivariate density.

3.4.2.3 Saturation

This check also suggested an improvement over the previous models, with better tail behavior and less bias in the proportion under-saturated measure.

3.4.2.4 R-square

The Bayesian \(R^2\) estimates below indicated an improvement from the previous models.

         Estimate Est.Error  Q2.5 Q97.5
R2logn2o    0.606     0.025 0.551 0.651
           Estimate Est.Error  Q2.5 Q97.5
R2logn2oeq    0.875     0.005 0.865 0.883

3.4.3 Covariate effects

3.4.3.1 N2O

The conditional effects plots for the covariate effects on N2O remained largely unchanged from the previous model.

Below are estimates of the conditional effects of the covariates on \(\sigma\) for N2O. These plots suggested a large effect of NO3 on the variance of N2O, but little to no effect of surface temperature.

3.4.3.2 Equilibrium N2O

The covariate effects on N2O remained largely the same as for the previous model.

The covariate effects on \(\sigma\) for N2O-eq suggested an negative effect of surface temperature and litte to no effect of elevation.

3.5 Model 5

In the next model, more complexity is added to the N2O component by including a covariate for lake surface area (log scale) as well as interactions between NO3 and log(area) and surface temperature.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

bf_n2o <- bf(log(n2o) ~ mo(no3_cat) +
               log_area +
               surftemp + 
               mo(no3_cat):log_area +
               mo(no3_cat):surftemp +
               (mo(no3_cat) | a | WSA9) + 
               (mo(no3_cat) | b | WSA9:state) + 
               (1 | c | WSA9:state:size_cat),
             sigma ~ log_area +
               mo(no3_cat) +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat), 
             family = gaussian())

bf_n2oeq <- bf(log(n2o_eq) ~ surftemp +
                 log_elev +
                 surftemp:log_elev +
                 (1 | a | WSA9) + 
                 (1 | b | WSA9:state) +
                 (1 | c | WSA9:state:size_cat),
             sigma ~ surftemp +
               log_elev +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat),
             family = gaussian())

priors <- c(
  prior(normal(2, 1), class = "Intercept", resp = "logn2o"),
  prior(normal(0, 1), class = "b", resp = "logn2o"),
  prior(exponential(2), class = "sd", resp = "logn2o"),
  prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2o"),
  prior(normal(0, 1), class = "b", dpar = "sigma", resp = "logn2o"),
  prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2o"),
  
  prior(normal(2, 1), class = "Intercept", resp = "logn2oeq"), 
  prior(normal(0, 1), class = "b", resp = "logn2oeq"), 
  prior(exponential(2), class = "sd", resp = "logn2oeq"), 
  prior(normal(-1, 2), class = "Intercept", dpar = "sigma", resp = "logn2oeq"),
  prior(normal(0, 1), class = "b", dpar = "sigma", resp = "logn2oeq"),
  prior(exponential(2), class = "sd", dpar = "sigma", resp = "logn2oeq"),
  
  prior(lkj(2), class = "rescor"),
  prior(lkj(2), class = "cor")
  )

n2o_mod5 <- brm(bf_n2o + 
                  bf_n2oeq +
                  set_rescor(rescor = TRUE),
                data = df_model, 
                prior = priors,
  control = list(adapt_delta = 0.975, max_treedepth = 12),
  #sample_prior = "only",
  save_pars = save_pars(all = TRUE),
  seed = 54741,
  chains=4, 
  iter=5000, 
  cores=4)

save(n2o_mod5, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod5.rda")

3.5.1 Summarize fit

Below is a summary of the fitted parameters along with MCMC convergence diagnostics.

 Family: MV(gaussian, gaussian) 
  Links: mu = identity; sigma = log
         mu = identity; sigma = log 
Formula: log(n2o) ~ mo(no3_cat) + log_area + surftemp + mo(no3_cat):log_area + mo(no3_cat):surftemp + (mo(no3_cat) | a | WSA9) + (mo(no3_cat) | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         sigma ~ log_area + mo(no3_cat) + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
         log(n2o_eq) ~ surftemp + log_elev + surftemp:log_elev + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         sigma ~ surftemp + log_elev + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
   Data: df_model (Number of observations: 984) 
  Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
         total post-warmup draws = 10000

Priors: 
b_logn2o ~ normal(0, 1)
b_logn2o_sigma ~ normal(0, 1)
b_logn2oeq ~ normal(0, 1)
b_logn2oeq_sigma ~ normal(0, 1)
Intercept_logn2o ~ normal(2, 1)
Intercept_logn2o_sigma ~ normal(-1, 2)
Intercept_logn2oeq ~ normal(2, 1)
Intercept_logn2oeq_sigma ~ normal(-1, 2)
L ~ lkj_corr_cholesky(2)
Lrescor ~ lkj_corr_cholesky(2)
<lower=0> sd_logn2o ~ exponential(2)
<lower=0> sd_logn2o_sigma ~ exponential(2)
<lower=0> sd_logn2oeq ~ exponential(2)
<lower=0> sd_logn2oeq_sigma ~ exponential(2)
simo_logn2o_mono3_cat:log_area1 ~ dirichlet(1)
simo_logn2o_mono3_cat:surftemp1 ~ dirichlet(1)
simo_logn2o_mono3_cat1 ~ dirichlet(1)
simo_logn2o_sigma_mono3_cat1 ~ dirichlet(1)

Group-Level Effects: 
~WSA9 (Number of levels: 9) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(logn2o_Intercept)                        0.048     0.019    0.020    0.094 1.000
sd(logn2o_mono3_cat)                        0.081     0.050    0.007    0.199 1.003
sd(logn2oeq_Intercept)                      0.034     0.011    0.018    0.062 1.000
sd(sigma_logn2o_Intercept)                  0.111     0.076    0.006    0.293 1.000
sd(sigma_logn2oeq_Intercept)                0.209     0.102    0.036    0.445 1.001
cor(logn2o_Intercept,logn2o_mono3_cat)     -0.056     0.360   -0.713    0.644 1.000
cor(logn2o_Intercept,logn2oeq_Intercept)    0.464     0.284   -0.173    0.885 1.000
cor(logn2o_mono3_cat,logn2oeq_Intercept)    0.259     0.341   -0.467    0.824 1.000
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         4413     4624
sd(logn2o_mono3_cat)                         1412     2265
sd(logn2oeq_Intercept)                       4061     6633
sd(sigma_logn2o_Intercept)                   2790     4064
sd(sigma_logn2oeq_Intercept)                 2176     1898
cor(logn2o_Intercept,logn2o_mono3_cat)       5823     6525
cor(logn2o_Intercept,logn2oeq_Intercept)     4935     6214
cor(logn2o_mono3_cat,logn2oeq_Intercept)     4684     4770

~WSA9:state (Number of levels: 96) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(logn2o_Intercept)                        0.046     0.014    0.016    0.072 1.001
sd(logn2o_mono3_cat)                        0.097     0.024    0.053    0.146 1.001
sd(logn2oeq_Intercept)                      0.033     0.003    0.027    0.040 1.001
sd(sigma_logn2o_Intercept)                  0.207     0.088    0.024    0.369 1.007
sd(sigma_logn2oeq_Intercept)                0.285     0.056    0.177    0.395 1.002
cor(logn2o_Intercept,logn2o_mono3_cat)     -0.265     0.284   -0.762    0.336 1.001
cor(logn2o_Intercept,logn2oeq_Intercept)    0.163     0.200   -0.232    0.559 1.005
cor(logn2o_mono3_cat,logn2oeq_Intercept)    0.266     0.209   -0.155    0.649 1.002
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                         1323     1765
sd(logn2o_mono3_cat)                         2612     2569
sd(logn2oeq_Intercept)                       3321     5286
sd(sigma_logn2o_Intercept)                    776     1082
sd(sigma_logn2oeq_Intercept)                 2464     3702
cor(logn2o_Intercept,logn2o_mono3_cat)       1708     3060
cor(logn2o_Intercept,logn2oeq_Intercept)      960     1715
cor(logn2o_mono3_cat,logn2oeq_Intercept)      883     1843

~WSA9:state:size_cat (Number of levels: 352) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(logn2o_Intercept)                        0.035     0.015    0.004    0.062 1.004
sd(logn2oeq_Intercept)                      0.003     0.002    0.000    0.007 1.003
sd(sigma_logn2o_Intercept)                  0.479     0.056    0.374    0.591 1.006
sd(sigma_logn2oeq_Intercept)                0.260     0.052    0.160    0.360 1.001
cor(logn2o_Intercept,logn2oeq_Intercept)    0.235     0.413   -0.658    0.872 1.002
                                         Bulk_ESS Tail_ESS
sd(logn2o_Intercept)                          819     1375
sd(logn2oeq_Intercept)                       1569     3553
sd(sigma_logn2o_Intercept)                   1318     3346
sd(sigma_logn2oeq_Intercept)                 2326     3796
cor(logn2o_Intercept,logn2oeq_Intercept)     2950     5425

Population-Level Effects: 
                           Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS Tail_ESS
logn2o_Intercept              2.380     0.055    2.273    2.487 1.001     4020     6632
sigma_logn2o_Intercept       -1.596     0.097   -1.789   -1.408 1.002     4961     6145
logn2oeq_Intercept            3.116     0.051    3.019    3.218 1.000     6860     7546
sigma_logn2oeq_Intercept     -1.922     0.374   -2.639   -1.179 1.000     7865     7774
logn2o_log_area               0.029     0.003    0.023    0.034 1.000     9054     8090
logn2o_surftemp              -0.025     0.002   -0.029   -0.021 1.000     3996     7106
sigma_logn2o_log_area        -0.095     0.020   -0.135   -0.055 1.001     6068     7491
logn2oeq_surftemp            -0.042     0.002   -0.046   -0.039 1.000     7418     8290
logn2oeq_log_elev            -0.080     0.008   -0.097   -0.065 1.000     6834     7865
logn2oeq_surftemp:log_elev    0.003     0.000    0.002    0.003 1.000     7339     7992
sigma_logn2oeq_surftemp      -0.065     0.010   -0.085   -0.046 1.000     9671     8132
sigma_logn2oeq_log_elev      -0.018     0.038   -0.096    0.054 1.000     6265     7038
logn2o_mono3_cat              0.026     0.127   -0.226    0.275 1.004     1971     3252
logn2o_mono3_cat:log_area    -0.036     0.010   -0.054   -0.016 1.001     2602     4549
logn2o_mono3_cat:surftemp     0.014     0.006    0.003    0.026 1.004     1478     2416
sigma_logn2o_mono3_cat        0.246     0.036    0.179    0.321 1.001     4246     6738

Simplex Parameters: 
                              Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS
logn2o_mono3_cat1[1]             0.026     0.024    0.001    0.089 1.001     4261
logn2o_mono3_cat1[2]             0.091     0.066    0.005    0.252 1.001     1875
logn2o_mono3_cat1[3]             0.250     0.146    0.034    0.615 1.002     2027
logn2o_mono3_cat1[4]             0.633     0.166    0.206    0.867 1.003     1411
logn2o_mono3_cat:log_area1[1]    0.060     0.041    0.005    0.161 1.000     4395
logn2o_mono3_cat:log_area1[2]    0.042     0.039    0.001    0.142 1.000     7129
logn2o_mono3_cat:log_area1[3]    0.297     0.161    0.047    0.681 1.000     5220
logn2o_mono3_cat:log_area1[4]    0.602     0.176    0.166    0.865 1.000     4431
logn2o_mono3_cat:surftemp1[1]    0.043     0.040    0.006    0.144 1.002     3541
logn2o_mono3_cat:surftemp1[2]    0.080     0.056    0.015    0.222 1.001     3667
logn2o_mono3_cat:surftemp1[3]    0.276     0.111    0.105    0.573 1.001     3634
logn2o_mono3_cat:surftemp1[4]    0.601     0.142    0.168    0.785 1.002     2731
sigma_logn2o_mono3_cat1[1]       0.131     0.074    0.010    0.288 1.000     6840
sigma_logn2o_mono3_cat1[2]       0.151     0.096    0.010    0.367 1.000     7630
sigma_logn2o_mono3_cat1[3]       0.444     0.149    0.149    0.734 1.001     6331
sigma_logn2o_mono3_cat1[4]       0.275     0.138    0.026    0.544 1.001     4902
                              Tail_ESS
logn2o_mono3_cat1[1]              5305
logn2o_mono3_cat1[2]              3916
logn2o_mono3_cat1[3]              2856
logn2o_mono3_cat1[4]              2439
logn2o_mono3_cat:log_area1[1]     3509
logn2o_mono3_cat:log_area1[2]     6046
logn2o_mono3_cat:log_area1[3]     5683
logn2o_mono3_cat:log_area1[4]     4505
logn2o_mono3_cat:surftemp1[1]     3002
logn2o_mono3_cat:surftemp1[2]     2580
logn2o_mono3_cat:surftemp1[3]     3352
logn2o_mono3_cat:surftemp1[4]     2289
sigma_logn2o_mono3_cat1[1]        4269
sigma_logn2o_mono3_cat1[2]        5795
sigma_logn2o_mono3_cat1[3]        6964
sigma_logn2o_mono3_cat1[4]        5797

Residual Correlations: 
                        Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS Tail_ESS
rescor(logn2o,logn2oeq)    0.141     0.038    0.066    0.216 1.000    11829     8204

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

3.5.2 Model checks

Again, the same PPCs as above were performed for this model. #### N2O PPC This PPC for N2O looked similar to the previous model.

3.5.2.1 Equilibrium N2O

Again, the PPCs for this model were similar to the previous model, which was unsurprising given that it was the same model for N2O-eq.

3.5.2.2 Bivariate

This PPC was also similar to the previous model.

3.5.2.3 Saturation

This check was also similar to the prevoius model, with perhaps slightly less bias in the proportion unsaturated estimates. There is also a potentially concerning extreme prediction in the observed vs predicted PPC.

3.5.2.4 R-square

         Estimate Est.Error  Q2.5 Q97.5
R2logn2o    0.629      0.03 0.563  0.68
           Estimate Est.Error  Q2.5 Q97.5
R2logn2oeq    0.874     0.005 0.864 0.882

3.5.3 Covariate effects

3.5.3.1 N2O

The conditional effects plot for the covariate effects N2O suggested a similar effect of NO3, but interesting interactions between NO3 and lake area and NO3 and surface temperature. For lake area, the effect was estimated to be larger and more negative at the highest levels of NO3; and slightly negative at the lowest level of NO3. For surface temperature, the effect was estimated to be largest and positive at the highest level of NO3; and negative at the lowest level of NO3.

The estimated covariate effects on \(\sigma\) suggested a negative relationship with log(area) and a positive relationship, again, with NO3.

3.5.3.2 Equilibrium N2O

The estimated covariate effect on N2O remained largely the same as estimated in the previous model.

3.6 A Final Model

As demonstrated above, models excluding the NO3 covariate consistently resulted in poorer fits to to the observed dissolved N2O data. Including surface temperature and elevation in the equilibrium N2O part of the model resulted in substantially improved replication of key aspects of the observed data. Likewise, added flexibility in the distributional terms for both dissolved and equilibrium N2O led to improvements.

To make inferences from this model for N2O in the population of interest, however, the included covariates needed to be (1) fully observed across that population or (2) their missingness needed to be modeled. For the lake area and elevation covariates, data was available for all lakes from previously compiled geospatial databases. However, neither surface temperature or NO3 were observed for lakes outside of the sample. They were partially observed with respect to the target population. Their missingness needed to be accounted for in a model. Therefore, a more complex model was constructed below that included surface temperature and NO3 as additional responses conditioned on the survey design variables and fully observed covariates. This approach to inference for N2O was similar to a Bayesian structural equation model (Merkle et al. 2021; Merkle and Rosseel 2018). The main details of the logical dependence structure could be characterized as:

\[\begin{align} \color{#1F449C}{\boldsymbol{N_2O_{diss}}} &=\sim Survey + Area + \color{#F05039}{\boldsymbol{NO_3}} + \color{#EEBAB4}{\boldsymbol{Temp}} \\ \color{#A8B6CC}{\boldsymbol{N_2O_{equil}}} &=\sim Survey + Elev + \color{#EEBAB4}{\boldsymbol{Temp}}\\ \color{#F05039}{\boldsymbol{NO_3}} &=\sim Survey + Area + \color{#EEBAB4}{\boldsymbol{Temp}} \\ \color{#EEBAB4}{\boldsymbol{Temp}} &=\sim Survey + Lat + Elev + Day \end{align}\]

Variables in color text above were treated as partially observed with respect to the population of interest (i.e., observed only in the sample), whereas variables in black text were considered fully observed. The partially observed variables, being dissolved and equilibrium N2O, NO3, and surface temperature, were each modeled conditional on the survey design variables and other partially and/or fully observed covariates. This structural equation approach requires a more complex set of post-processing steps compared to a typical MRP analysis. In order to propagate estimates and uncertainty through the dependency structure and make inferences, the fitted model was used to first predict surface temperature in the target population, since it depended only on the fully observed covariates. That predictive distribution was then used alongside the relevant fully observed covariates to predict NO3 in the target population. Finally, the predictive distributions for termperature and NO3 were used to predict the N2O responses. These steps were carried out in the “Predict to population” section to follow.

In the final model below, the submodel for surface temperature assumed a Gamma distributed error distribution and the linear predictor included the survey design variables, latitude, elevation, and julian date. The shape parameter was also modeled as a function of latitude to address increasing response variance along the latitudinal gradient. The NO3 submodel was a cumulative logit formulation and the linear predictor included all of the survey factors as well as surface temperature and lake area.

The N2O and N2O-eq responses were each modeled with Gamma distributed errors, but with the same covariate structure as in model 5. The same structure was also employed for the shape terms in these responses, corresponding to the \(\sigma\) terms in the previous model. Though not shown in this document, the Gamma error structure appeared to result in slightly better performance in the predictive checks compared to the Gaussian errors in previous models. This was primarily apparent in the saturation ratio checks, which may have been more sensitive to model performance in the tails of the N2O responses. Others have also indicated that the Gamma error distribution can work well for dissolved N2O data (Webb et al. 2019).

Note that there was no residual correlation term for this model, since the residuals are undefined for the Gamma and cumulative logit models. Dropping the observation-level residual correlation term was deemed a reasonable compromise that enabled modeling the missingness of NO3, in particular. Nevertheless, the random intercepts again allowed for potential correlations between responses at the group levels.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")

bf_n2o <- bf(n2o ~ mo(no3_cat) +
               log_area +
               surftemp + 
               mo(no3_cat):log_area +
               mo(no3_cat):surftemp +
               (mo(no3_cat) | a | WSA9) + 
               (mo(no3_cat) | b | WSA9:state) + 
               (1 | c | WSA9:state:size_cat),
             shape ~ log_area +
               mo(no3_cat) +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat),
             family = Gamma(link = "log"))

bf_n2oeq <- bf(n2o_eq ~ surftemp +
                 log_elev +
                 surftemp:log_elev +
                 (1 | a | WSA9) + 
                 (1 | b | WSA9:state) +
                 (1 | c | WSA9:state:size_cat),
             shape ~ surftemp +
               log_elev +
               (1 | WSA9) + 
               (1 | WSA9:state) + 
               (1 | WSA9:state:size_cat),
             family = Gamma(link = "log"))

bf_temp <- bf(surftemp ~ lat +
                s(log_elev) +
                s(jdate) +
                (1 | a | WSA9) + 
                (1 | b | WSA9:state) +
                (1 | c | WSA9:state:size_cat),
              shape ~ lat,
              family = Gamma(link = "log"))

bf_no3 <- bf(no3_cat ~ surftemp +
               log_area +
               (1 | a | WSA9) +
               (1 | b | WSA9:state) +
               (1 | c | WSA9:state:size_cat),
             family = cumulative(link = "logit", threshold="flexible"))

priors <- c(
  prior(normal(2, 1), class = "Intercept", resp = "n2o"),
  prior(normal(0, 1), class = "b", resp = "n2o"),
  prior(exponential(2), class = "sd", resp = "n2o"),
  prior(normal(5, 4), class = "Intercept", dpar = "shape", resp = "n2o"),
  prior(normal(0, 1), class = "b", dpar = "shape", resp = "n2o"),
  prior(exponential(2), class = "sd", dpar = "shape", resp = "n2o"),
  
  prior(normal(2, 1), class = "Intercept", resp = "n2oeq"), 
  prior(normal(0, 1), class = "b", resp = "n2oeq"),  
  prior(exponential(2), class = "sd", resp = "n2oeq"),
  prior(normal(5, 4), class = "Intercept", dpar = "shape", resp = "n2oeq"),
  prior(normal(0, 1), class = "b", dpar = "shape", resp = "n2oeq"),
  prior(exponential(2), class = "sd", dpar = "shape", resp = "n2oeq"),
  
  prior(normal(3, 1), class = "Intercept", resp = "surftemp"), 
  prior(normal(0, 1), class = "b", resp = "surftemp"), 
  prior(exponential(0.5), class = "sds", resp = "surftemp"),
  prior(exponential(2), class = "sd", resp = "surftemp"),
  prior(normal(5, 4), class = "Intercept", dpar = "shape", resp = "surftemp"),
  prior(normal(0, 1), class = "b", dpar = "shape", resp = "surftemp"),
  
  prior(normal(0, 3), class = "Intercept", resp = "no3cat"),
  prior(normal(0, 1), class = "b", resp = "no3cat"),
  prior(exponential(1), class = "sd", resp = "no3cat"),
  
  prior(lkj(2), class = "cor")
  )

n2o_mod6 <- brm(bf_n2o + 
                  bf_n2oeq + 
                  bf_temp + 
                  bf_no3 + 
                  set_rescor(rescor = FALSE),
                data = df_model, 
                prior = priors,
  control = list(adapt_delta = 0.975, max_treedepth = 14),
  #sample_prior = "only",
  save_pars = save_pars(all = TRUE),
  seed = 85132,#14548,
  #init = my_inits,
  init_r = 0.5,
  chains=4, 
  iter=5000, 
  cores=4)

save(n2o_mod6, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod6.rda")

3.6.1 Summarize fit

Below is a summary of the fitted parameters and MCMC diagnostics.

 Family: MV(gamma, gamma, gamma, cumulative) 
  Links: mu = log; shape = log
         mu = log; shape = log
         mu = log; shape = log
         mu = logit; disc = identity 
Formula: n2o ~ mo(no3_cat) + log_area + surftemp + mo(no3_cat):log_area + mo(no3_cat):surftemp + (mo(no3_cat) | a | WSA9) + (mo(no3_cat) | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         shape ~ log_area + mo(no3_cat) + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
         n2o_eq ~ surftemp + log_elev + surftemp:log_elev + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         shape ~ surftemp + log_elev + (1 | WSA9) + (1 | WSA9:state) + (1 | WSA9:state:size_cat)
         surftemp ~ lat + s(log_elev) + s(jdate) + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
         shape ~ lat
         no3_cat ~ surftemp + log_area + (1 | a | WSA9) + (1 | b | WSA9:state) + (1 | c | WSA9:state:size_cat) 
   Data: df_model (Number of observations: 984) 
  Draws: 4 chains, each with iter = 5000; warmup = 2500; thin = 1;
         total post-warmup draws = 10000

Priors: 
b_n2o ~ normal(0, 1)
b_n2o_shape ~ normal(0, 1)
b_n2oeq ~ normal(0, 1)
b_n2oeq_shape ~ normal(0, 1)
b_no3cat ~ normal(0, 1)
b_surftemp ~ normal(0, 1)
b_surftemp_shape ~ normal(0, 1)
Intercept_n2o ~ normal(2, 1)
Intercept_n2o_shape ~ normal(5, 4)
Intercept_n2oeq ~ normal(2, 1)
Intercept_n2oeq_shape ~ normal(5, 4)
Intercept_no3cat ~ normal(0, 3)
Intercept_surftemp ~ normal(3, 1)
Intercept_surftemp_shape ~ normal(5, 4)
L ~ lkj_corr_cholesky(2)
<lower=0> sd_n2o ~ exponential(2)
<lower=0> sd_n2o_shape ~ exponential(2)
<lower=0> sd_n2oeq ~ exponential(2)
<lower=0> sd_n2oeq_shape ~ exponential(2)
<lower=0> sd_no3cat ~ exponential(1)
<lower=0> sd_surftemp ~ exponential(2)
<lower=0> sds_surftemp ~ exponential(0.5)
simo_n2o_mono3_cat:log_area1 ~ dirichlet(1)
simo_n2o_mono3_cat:surftemp1 ~ dirichlet(1)
simo_n2o_mono3_cat1 ~ dirichlet(1)
simo_n2o_shape_mono3_cat1 ~ dirichlet(1)

Smooth Terms: 
                          Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS Tail_ESS
sds(surftemp_slog_elev_1)    1.161     0.370    0.638    2.079 1.001     2264     4174
sds(surftemp_sjdate_1)       0.571     0.277    0.226    1.273 1.000     2679     4853

Group-Level Effects: 
~WSA9 (Number of levels: 9) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(n2o_Intercept)                           0.048     0.018    0.020    0.091 1.000
sd(n2o_mono3_cat)                           0.045     0.035    0.002    0.129 1.003
sd(n2oeq_Intercept)                         0.033     0.011    0.018    0.061 1.000
sd(surftemp_Intercept)                      0.031     0.014    0.011    0.064 1.001
sd(no3cat_Intercept)                        0.690     0.256    0.296    1.308 1.000
sd(shape_n2o_Intercept)                     0.211     0.141    0.011    0.535 1.000
sd(shape_n2oeq_Intercept)                   0.402     0.183    0.075    0.814 1.001
cor(n2o_Intercept,n2o_mono3_cat)           -0.049     0.336   -0.667    0.614 1.000
cor(n2o_Intercept,n2oeq_Intercept)          0.393     0.268   -0.202    0.824 1.000
cor(n2o_mono3_cat,n2oeq_Intercept)          0.102     0.328   -0.559    0.686 1.000
cor(n2o_Intercept,surftemp_Intercept)      -0.350     0.296   -0.839    0.285 1.000
cor(n2o_mono3_cat,surftemp_Intercept)       0.089     0.333   -0.564    0.703 1.000
cor(n2oeq_Intercept,surftemp_Intercept)    -0.167     0.299   -0.705    0.437 1.000
cor(n2o_Intercept,no3cat_Intercept)        -0.057     0.295   -0.605    0.522 1.000
cor(n2o_mono3_cat,no3cat_Intercept)         0.141     0.333   -0.539    0.724 1.002
cor(n2oeq_Intercept,no3cat_Intercept)       0.272     0.274   -0.305    0.740 1.001
cor(surftemp_Intercept,no3cat_Intercept)    0.185     0.300   -0.436    0.718 1.000
                                         Bulk_ESS Tail_ESS
sd(n2o_Intercept)                            3011     2931
sd(n2o_mono3_cat)                            1540     3502
sd(n2oeq_Intercept)                          3147     4572
sd(surftemp_Intercept)                       3705     4498
sd(no3cat_Intercept)                         4184     5618
sd(shape_n2o_Intercept)                      2379     3641
sd(shape_n2oeq_Intercept)                    2208     1617
cor(n2o_Intercept,n2o_mono3_cat)             6558     6134
cor(n2o_Intercept,n2oeq_Intercept)           4604     6010
cor(n2o_mono3_cat,n2oeq_Intercept)           3241     5029
cor(n2o_Intercept,surftemp_Intercept)        4744     5916
cor(n2o_mono3_cat,surftemp_Intercept)        5246     6447
cor(n2oeq_Intercept,surftemp_Intercept)      7342     7508
cor(n2o_Intercept,no3cat_Intercept)          5152     6479
cor(n2o_mono3_cat,no3cat_Intercept)          3435     5897
cor(n2oeq_Intercept,no3cat_Intercept)        6449     7400
cor(surftemp_Intercept,no3cat_Intercept)     6490     7928

~WSA9:state (Number of levels: 96) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(n2o_Intercept)                           0.047     0.013    0.021    0.072 1.004
sd(n2o_mono3_cat)                           0.101     0.019    0.068    0.142 1.001
sd(n2oeq_Intercept)                         0.033     0.003    0.026    0.040 1.001
sd(surftemp_Intercept)                      0.035     0.006    0.023    0.047 1.000
sd(no3cat_Intercept)                        0.878     0.128    0.649    1.147 1.000
sd(shape_n2o_Intercept)                     0.383     0.178    0.032    0.707 1.004
sd(shape_n2oeq_Intercept)                   0.561     0.114    0.336    0.781 1.002
cor(n2o_Intercept,n2o_mono3_cat)           -0.145     0.254   -0.602    0.376 1.002
cor(n2o_Intercept,n2oeq_Intercept)          0.183     0.189   -0.180    0.549 1.003
cor(n2o_mono3_cat,n2oeq_Intercept)          0.201     0.164   -0.122    0.519 1.002
cor(n2o_Intercept,surftemp_Intercept)      -0.023     0.237   -0.476    0.438 1.004
cor(n2o_mono3_cat,surftemp_Intercept)      -0.232     0.215   -0.644    0.194 1.001
cor(n2oeq_Intercept,surftemp_Intercept)    -0.134     0.190   -0.494    0.246 1.000
cor(n2o_Intercept,no3cat_Intercept)         0.462     0.211    0.018    0.822 1.004
cor(n2o_mono3_cat,no3cat_Intercept)         0.145     0.200   -0.251    0.531 1.000
cor(n2oeq_Intercept,no3cat_Intercept)       0.054     0.140   -0.220    0.329 1.000
cor(surftemp_Intercept,no3cat_Intercept)   -0.231     0.189   -0.586    0.154 1.001
                                         Bulk_ESS Tail_ESS
sd(n2o_Intercept)                            1025     1337
sd(n2o_mono3_cat)                            3366     4975
sd(n2oeq_Intercept)                          2809     4611
sd(surftemp_Intercept)                       4124     5116
sd(no3cat_Intercept)                         4389     6247
sd(shape_n2o_Intercept)                       649     1304
sd(shape_n2oeq_Intercept)                    1908     1810
cor(n2o_Intercept,n2o_mono3_cat)             1069     1955
cor(n2o_Intercept,n2oeq_Intercept)            794     1260
cor(n2o_mono3_cat,n2oeq_Intercept)            833     1873
cor(n2o_Intercept,surftemp_Intercept)        1849     3618
cor(n2o_mono3_cat,surftemp_Intercept)        2626     4267
cor(n2oeq_Intercept,surftemp_Intercept)      6340     6860
cor(n2o_Intercept,no3cat_Intercept)           893     1944
cor(n2o_mono3_cat,no3cat_Intercept)          1746     3085
cor(n2oeq_Intercept,no3cat_Intercept)        6378     7983
cor(surftemp_Intercept,no3cat_Intercept)     3573     5949

~WSA9:state:size_cat (Number of levels: 352) 
                                         Estimate Est.Error l-95% CI u-95% CI  Rhat
sd(n2o_Intercept)                           0.038     0.014    0.006    0.064 1.011
sd(n2oeq_Intercept)                         0.004     0.002    0.000    0.008 1.009
sd(surftemp_Intercept)                      0.010     0.007    0.000    0.024 1.003
sd(no3cat_Intercept)                        0.308     0.182    0.016    0.673 1.002
sd(shape_n2o_Intercept)                     0.895     0.110    0.684    1.114 1.002
sd(shape_n2oeq_Intercept)                   0.511     0.104    0.309    0.715 1.002
cor(n2o_Intercept,n2oeq_Intercept)          0.310     0.349   -0.486    0.841 1.004
cor(n2o_Intercept,surftemp_Intercept)       0.015     0.365   -0.677    0.705 1.000
cor(n2oeq_Intercept,surftemp_Intercept)    -0.102     0.381   -0.761    0.659 1.001
cor(n2o_Intercept,no3cat_Intercept)        -0.090     0.342   -0.716    0.601 1.001
cor(n2oeq_Intercept,no3cat_Intercept)      -0.143     0.359   -0.757    0.611 1.001
cor(surftemp_Intercept,no3cat_Intercept)    0.173     0.378   -0.599    0.807 1.001
                                         Bulk_ESS Tail_ESS
sd(n2o_Intercept)                             580     1036
sd(n2oeq_Intercept)                          1062     3160
sd(surftemp_Intercept)                       1917     3889
sd(no3cat_Intercept)                         1078     2386
sd(shape_n2o_Intercept)                      1068     2786
sd(shape_n2oeq_Intercept)                    1397     2071
cor(n2o_Intercept,n2oeq_Intercept)           2099     4705
cor(n2o_Intercept,surftemp_Intercept)        4876     6414
cor(n2oeq_Intercept,surftemp_Intercept)      4195     5741
cor(n2o_Intercept,no3cat_Intercept)          3188     5334
cor(n2oeq_Intercept,no3cat_Intercept)        2749     4946
cor(surftemp_Intercept,no3cat_Intercept)     2607     5750

Population-Level Effects: 
                         Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS Tail_ESS
n2o_Intercept               2.392     0.056    2.285    2.500 1.000     3063     5517
shape_n2o_Intercept         3.215     0.189    2.849    3.589 1.001     3997     6108
n2oeq_Intercept             3.111     0.053    3.011    3.218 1.000     5146     6075
shape_n2oeq_Intercept       3.873     0.751    2.385    5.326 1.001     5619     6535
surftemp_Intercept          3.791     0.060    3.672    3.906 1.000     7414     7632
shape_surftemp_Intercept    8.637     0.460    7.721    9.522 1.001    10817     7718
no3cat_Intercept[1]        -3.025     0.615   -4.258   -1.864 1.000     5932     6622
no3cat_Intercept[2]        -2.059     0.605   -3.274   -0.903 1.000     6278     6695
no3cat_Intercept[3]        -1.027     0.600   -2.235    0.115 1.000     6689     6957
no3cat_Intercept[4]        -0.028     0.602   -1.247    1.113 1.000     7002     6940
n2o_log_area                0.028     0.003    0.022    0.034 1.000     6958     7668
n2o_surftemp               -0.025     0.002   -0.029   -0.021 1.000     3145     6260
shape_n2o_log_area          0.190     0.041    0.110    0.271 1.000     4322     5605
n2oeq_surftemp             -0.042     0.002   -0.045   -0.038 1.000     5836     6494
n2oeq_log_elev             -0.080     0.008   -0.097   -0.064 1.000     5425     6234
n2oeq_surftemp:log_elev     0.002     0.000    0.002    0.003 1.000     5857     6696
shape_n2oeq_surftemp        0.131     0.020    0.092    0.171 1.001     6725     7112
shape_n2oeq_log_elev        0.030     0.077   -0.117    0.186 1.001     4914     6636
surftemp_lat               -0.016     0.001   -0.019   -0.013 1.000     7349     7598
shape_surftemp_lat         -0.105     0.011   -0.127   -0.083 1.000    11330     7919
no3cat_surftemp            -0.141     0.023   -0.187   -0.096 1.001     6713     7328
no3cat_log_area             0.068     0.035   -0.001    0.137 1.000    11692     8177
surftemp_slog_elev_1       -3.477     0.479   -4.414   -2.557 1.000     5891     6330
surftemp_sjdate_1          -0.008     0.528   -1.074    1.017 1.000     4010     5523
n2o_mono3_cat               0.007     0.087   -0.172    0.175 1.004     1650     1855
n2o_mono3_cat:log_area     -0.046     0.009   -0.063   -0.027 1.001     2079     2821
n2o_mono3_cat:surftemp      0.018     0.004    0.009    0.026 1.004     1417     1621
shape_n2o_mono3_cat        -0.510     0.070   -0.649   -0.375 1.001     4691     6283

Simplex Parameters: 
                           Estimate Est.Error l-95% CI u-95% CI  Rhat Bulk_ESS Tail_ESS
n2o_mono3_cat1[1]             0.025     0.023    0.001    0.083 1.000     4899     5237
n2o_mono3_cat1[2]             0.183     0.111    0.014    0.425 1.002     1056     3343
n2o_mono3_cat1[3]             0.408     0.158    0.103    0.725 1.002     2167     4583
n2o_mono3_cat1[4]             0.384     0.169    0.058    0.713 1.003     1608     3021
n2o_mono3_cat:log_area1[1]    0.046     0.029    0.003    0.112 1.000     4018     3309
n2o_mono3_cat:log_area1[2]    0.033     0.028    0.001    0.104 1.001     6173     4948
n2o_mono3_cat:log_area1[3]    0.289     0.134    0.057    0.598 1.000     3286     4461
n2o_mono3_cat:log_area1[4]    0.631     0.140    0.301    0.864 1.000     3186     4184
n2o_mono3_cat:surftemp1[1]    0.028     0.019    0.003    0.060 1.001     3744     3410
n2o_mono3_cat:surftemp1[2]    0.066     0.033    0.011    0.128 1.001     3821     3213
n2o_mono3_cat:surftemp1[3]    0.281     0.079    0.122    0.431 1.003     2897     2971
n2o_mono3_cat:surftemp1[4]    0.625     0.088    0.461    0.798 1.003     2740     3106
shape_n2o_mono3_cat1[1]       0.116     0.067    0.009    0.263 1.001     5363     4297
shape_n2o_mono3_cat1[2]       0.149     0.096    0.008    0.365 1.001     3469     3637
shape_n2o_mono3_cat1[3]       0.401     0.151    0.116    0.703 1.001     4122     5848
shape_n2o_mono3_cat1[4]       0.334     0.143    0.051    0.604 1.001     3853     4561

Family Specific Parameters: 
            Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
disc_no3cat    1.000     0.000    1.000    1.000   NA       NA       NA

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

3.6.2 Model checks

Below, the same PPCs for N2O and N2O-eq were employed as before. #### N2O PPC The PPCs for N2O from this model were similarly reasonable as for models 4 and 5 above.

Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'scatter_avg' by default.

3.6.2.1 Equilibrium N2O PPC

Again, the PPCs for N2O-eq in this model were similar to those for models 4 and 5.

Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'stat_2d' by default.
Using all posterior draws for ppc type 'scatter_avg' by default.

3.6.2.2 Bivariate PPC

This model again provided a very reasonable representation of the bivariate relationship between N2O and N2O-eq (below).

3.6.2.3 Saturation PPC

The saturation ratio PPCs below show similar behavior as with models 4 and 5 above, but with perhaps slightly less bias in the predictions for the proportion of undersaturated waterbodies and fewer extreme predictions for the means and standard deviations. The observed vs. predicted PPC also appears to have a better behaved variance and no extreme predictions, compared to models 4 and 5 with the lognormal errors.

The plot below shows the same PPC, but for the “test” or second-vist data. Overall, the model looked to perform similarly as with the data used to fit it.

3.6.2.4 R-square

Below are estimates for the Bayesian \(R^2\), which were largely similar for N2O and N2O-eq as with models 4 and 5 above. The \(R^2\) for the surface temperature response also suggested a fairly good fit.

      Estimate Est.Error  Q2.5 Q97.5
R2n2o    0.646     0.059 0.503 0.731
        Estimate Est.Error  Q2.5 Q97.5
R2n2oeq    0.863     0.006 0.851 0.874
           Estimate Est.Error  Q2.5 Q97.5
R2surftemp    0.744      0.01 0.723 0.763

Below are the same \(R^2\) estimates, but for the second-visit data. That these estimates are similar to those for the data used to fit the model, suggesting that the model may perform similarly well out-of-sample.

      Estimate Est.Error  Q2.5 Q97.5
R2n2o    0.607     0.137 0.325  0.85
        Estimate Est.Error Q2.5 Q97.5
R2n2oeq    0.857     0.008 0.84 0.872
           Estimate Est.Error  Q2.5 Q97.5
R2surftemp     0.75     0.018 0.715 0.783

3.6.3 Covariate effects

3.6.3.1 N2O

The conditional effects plot for the covariate effects N2O suggested a similar effect of NO3, but interesting interactions between NO3 and lake area and NO3 and surface temperature. For lake area, the effect was estimated to be larger and more negative at the highest levels of NO3; and slightly negative at the lowest level of NO3. For surface temperature, the effect was estimated to be largest and positive at the highest level of NO3; and negative at the lowest level of NO3.

The estimated covariate effects on \(\sigma\) suggested a negative relationship with log(area) and a positive relationship, again, with NO3.

3.6.3.2 Equilibrium N2O

The estimated covariate effect on N2O remained largely the same as estimated in the previous model.

4 Predict to population

As previously described, in order to make inferences to the population of interest, the final model above was used to, first, predict surface temperature in the target population, since it depended only on the fully observed covariates. Next, the predictive distribution for surface temperature was used, along with the relevant fully observed covariates, to predict NO3 in the target population. Finally, the predictive distributions for temperature and NO3 were used to predict the N2O responses. The code for these steps is outlined in the following.

The first step used the final model to predict to the population:

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sframe.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod6.rda")

predict_temp <- sframe %>%
  mutate(jdate = 205) %>%
  add_predicted_draws(n2o_mod6, resp=c("surftemp"), 
                      allow_new_levels = TRUE, 
                      cores =1, 
                      ndraws = 500) %>%
  mutate(surftemp = .prediction)

save(predict_temp, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_temp.rda")

NO3 was next predicted. Note that the posterior predictive distribution for NO3 was subsampled in order to minimize excess simulations

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod6.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_temp.rda")

temp_X <- predict_temp %>% # select relevant columns as predictors
  ungroup() %>%
  select(WSA9,
         state,
         size_cat,
         log_area,
         .row,
         .draw,
         surftemp) %>%
  select(WSA9, state, size_cat, log_area, surftemp)


rm(predict_temp) # reduce memory
gc()

# set number of cores to use for parallel predictions
# and register the workers
cl <- parallel::makeCluster(5) 
doSNOW::registerDoSNOW(cl) 

# make a progress bar
pb <- txtProgressBar(max = 1500, style = 3)
progress <- function(n) setTxtProgressBar(pb, n)
opts <- list(progress = progress)

system.time( # approx 26 hrs with 5 workers & 500 draws from PPD
predict_no3 <- foreach(sub_X = isplitRows(temp_X, chunkSize = 155299), 
                       .combine = 'c',
                       .packages = c("brms"),
                       .options.snow = opts
                       ) %dopar% {
                         apply(brms::posterior_predict(n2o_mod6,
                                                 newdata = sub_X,
                                                 resp = "no3cat",
                                                 allow_new_levels = T,
                                                 ndraws = 500,
                                                 cores = 1), 2, sample, 1)
                         }
)


close(pb)
parallel::stopCluster(cl)

save(predict_no3, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_no3.rda")

Finally, N2O and N2O-eq were predicted using the surface temperature and nitrate predictions along with the survey variables and known covariates. Again, the posterior was subsampled in order to reduce excess simulations.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_no3.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_temp.rda")

# Assemble dataframe containing relevant covariates (known and predicted)
n2o_X <- predict_temp %>%
  ungroup() %>%
  mutate(no3_cat = predict_no3) %>%
  select(WSA9,
         state,
         size_cat,
         log_area,
         surftemp,
         log_elev,
         no3_cat)

# clear objects to reduce memory overhead
rm(predict_no3, predict_temp) 
gc()

# save the predictors for n2o and n2oeq
save(n2o_X, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_X.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_mod6.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_X.rda")

# set number of cores to use for parallel predictions
# and register the workers
cl <- parallel::makeCluster(6) 
doSNOW::registerDoSNOW(cl) 

# make a progress bar
pb <- txtProgressBar(max = 1500, style = 3)
progress <- function(n) setTxtProgressBar(pb, n)
opts <- list(progress = progress)

# make predictions in parallel
system.time(
predict_n2o <- foreach(sub_X = isplitRows(n2o_X, chunkSize = 155299),
                 .combine = rbind,
                 .options.snow = opts,
                 .packages = c("brms")) %dopar% {
  apply(posterior_predict(n2o_mod6,
                          newdata = sub_X,
                          resp = c("n2o", "n2oeq"),
                          allow_new_levels = T,
                          ndraws = 500,
                          cores = 1),
        2, sample, 1)
                   }
)

close(pb)
parallel::stopCluster(cl)

colnames(predict_n2o) <- c("n2o", "n2oeq")

save(predict_n2o, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_n2o.rda")

Finally, the predictions for all four partially observed responses were assembled into a new dataframe for use in inference.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_n2o.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_no3.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/predict_temp.rda")

all_predictions <- predict_temp %>%
  ungroup() %>%
  mutate(no3cat = predict_no3) %>%
  bind_cols(predict_n2o) %>%
  mutate(n2osat = n2o / n2oeq, # calculate saturation ratio
         .row = rep(1:465897, each = 500),
         .draw = rep(seq(1,500, 1), 465897)) %>%
  mutate(area_ha = exp(log_area)) %>% # include area on ha scale
  select(WSA9,
         state,
         size_cat,
         area_ha,
         lat,
         lon,
         .row,
         .draw,
         surftemp,
         no3cat,
         n2o,
         n2oeq,
         n2osat)

rm(predict_n2o, predict_temp, predict_no3) # clean up workspace for RAM
gc()
 

save(all_predictions, file = "C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/all_predictions.rda")

5 Population estimates

A number of estimates for the target population were assembled and presented below. First, the full posterior predictive distributions for dissolved N2O, equilibrium N2o, and the saturation ratio were assessed. These distributions summarized the predicted distribution of concentrations or ratios for all lakes in the population of interest and included parameter uncertainty propagated through the model. Next, population means were assessed, followed by comparisons of some model-based estimates to previously calculated design-based estimates.

5.1 Posterior predictive distributions

Below, a density plot summarized the posterior predictive distribution of N2O and N2O-eq concentrations across the target population of lakes, based on 500 draws from the posterior predictive distribution. Note that the x-axis was truncated at 50 nmol/L for a clearer visualization of the bulk of the predicted distribution. For reference, the max predicted value was 4403.2 nmol/L for dissolved N2O, 20.4 nmol/L for dissolved N2O, and 793.5 for the saturation ratio.

5.2 Estimated means

5.2.1 National

Below are density plots summarizing the posterior distribution of means for N2O concentrations and the saturation ratio for the target population (i.e., all US lakes > 1ha in the lower 48 states).

To illustrate the skewness in the predictive distribution for the saturation ratio, an estimate for the median ratio is shown below. The entire posterior distribution of the mean above is larger than 1, the ratio representing the boundary of under- vs. oversaturation. By comparison, the posterior estimate of the median below only included values less than one, suggesting that though the mean saturation ratio was greater than 1, most lakes in the national populaiton were undersaturated (i.e., ratio less than 1). In distributions with right-skew, the mean can often be considerably larger than the median.

Below is a plot of the posterior mean estimate for the proportion of unsaturated lakes at the national scale.

5.2.2 Ecoregion

Below are posterior estimates of the means for dissolved and equilibrium N2O and the saturation ratio by WSA9 ecoregion.

A plot of the posterior estimates for the median saturation ratio below indicated, again, that most lakes in each ecoregion were undersaturated (i.e., median << 1).

A plot of the estimates of the proportion of under-saturated lakes by ecoregion is below. A plot of the posterior estimates for the median saturation ratio below indicated, again, that most lakes in each ecoregion were undersaturated (i.e., median << 1).

5.2.3 State

Comparisons of mean estimates (posterior median, upper and lower 95th percentiles) by state are below. Density estimates were not included to minimize plot space.

Below, a plot of estimates for the mean (black circles) and median (grey circles) saturation ratio by state. A horizontal, dashed, black line is shown at ratio = 1, indicating the boundary for under- vs. oversaturation. Only a few states (e.g., NV, DE) had median estimates that were 1 or greater, suggesting that, for most states, most lakes were undersaturated.

Finally, a plot of the estimated proportion of undersaturated lakes for each state in the target population. Point estimates are the posterior median of the proportion and bars are the upper and lower boundaries of the central 95th percentile of the posterior distributions of proportions.

5.2.4 Size category

The estimated means by size category are below for dissolved and equilibrium N2O and the saturation ratio. Median estimates for the saturation ratio are also shown.

Mean vs. median below.

And, finally, the estimated proportion of undersaturated lakes in the target population by size category

5.3 Model- vs. design-based

Below, estimates from the model-based approach are compared to design-based estimates. In general, the model estimates were similar to the design-based estimates. Model estimates were typically within the confidence bounds of the design-based estimates, but with much greater precision. Improved precision was expected due to the “shrinkage” induced by the multilevel parameterization, which allowed some “borrowing” of information across the various levels of the survey factors.

5.3.1 Dissolved N2O

Below, National mean estimates for dissolved N2O from the model and design-based approaches were compared. The sample-based estimate was also included as a naive reference.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_survey_ests.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/all_predictions.rda")

all_predictions %>%
  group_by(.draw) %>%
  summarise(mean_n2o = mean(n2o)) %>%
  summarise(estimate = round(median(mean_n2o), 2), # posterior median
    LCL = round(quantile(mean_n2o, probs = 0.025), 2),
    UCL = round(quantile(mean_n2o, probs = 0.975), 2)) %>% 
  mutate(type = "model") %>%
  bind_rows(cbind(n2o_survey_ests[10, 2:4], type = rep("survey", 1))) %>%
  add_row(estimate = round(mean(df_model$n2o), 2),
          type = "sample") %>%
  print()

The black, vertical, dashed line in the figure below represents the mean of the sample.

Below, estimates were compared by ecoregion.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/all_predictions.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/n2o_survey_ests.rda")

all_predictions %>%
  group_by(WSA9, .draw) %>%
  summarise(mean_n2o = mean(n2o)) %>%
  group_by(WSA9, .groups = "drop") %>%
  summarise(estimate = round(median(mean_n2o), 2),
    LCL = round(quantile(mean_n2o, probs = 0.025), 2),
    UCL = round(quantile(mean_n2o, probs = 0.975), 2),
    .groups = "drop") %>% 
  mutate(ecoregion = factor(WSA9)) %>%
  mutate(type = "model") %>%
  select(ecoregion, estimate, LCL, UCL, type) %>%
  mutate(ecoregion = forcats::fct_reorder(ecoregion, estimate)) %>%
  bind_rows(cbind(n2o_survey_ests[-10,], type = rep("survey", 9))) %>%
  arrange(ecoregion) %>%
  print()
`summarise()` has grouped output by 'WSA9'. You can override using the `.groups`
argument.

Means were compared according to size categories below.

5.3.2 Saturation

Below, the same comparisons were made for the saturation estimates.

load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/df_model.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/all_predictions.rda")
load("C:/Users/rmartin/OneDrive - Environmental Protection Agency (EPA)/Documents/AE_Reservoirs/DissolvedGasNla/modelFiles/sat_survey_ests.rda")

all_predictions %>%
  group_by(.draw) %>%
  summarise(mean_sat = mean(n2osat), .groups = "drop") %>%
  summarise(estimate = round(median(mean_sat), 3),
    LCL = round(quantile(mean_sat, probs = 0.025), 3),
    UCL = round(quantile(mean_sat, probs = 0.975), 3),
    .groups = "drop") %>% 
  mutate(type = "model") %>%
  bind_rows(cbind(sat_survey_ests[10, 2:4], type = rep("survey", 1))) %>%
  add_row(estimate = round(mean(df_model$n2o / df_model$n2o_eq), 3),
          type = "sample") %>%
  print()

6 References

7 Session Info

sessionInfo()
R version 4.1.2 (2021-11-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 22000)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
 [1] brms_2.18.0      Rcpp_1.0.9       tidybayes_3.0.2  bayesplot_1.9.0  itertools_0.1-3 
 [6] iterators_1.0.14 foreach_1.5.2    future_1.28.0    forcats_0.5.2    stringr_1.5.0   
[11] purrr_0.3.5      readr_2.1.3      tidyr_1.2.1      tibble_3.1.8     tidyverse_1.3.2 
[16] dplyr_1.0.10     ggrepel_0.9.2    kableExtra_1.3.4 gridExtra_2.3    ggExtra_0.10.0  
[21] moments_0.14.1   ggpubr_0.4.0     ggplot2_3.4.0   

loaded via a namespace (and not attached):
  [1] readxl_1.4.1         backports_1.4.1      systemfonts_1.0.4    plyr_1.8.8          
  [5] igraph_1.3.5         svUnit_1.0.6         splines_4.1.2        listenv_0.8.0       
  [9] crosstalk_1.2.0      rstantools_2.2.0     inline_0.3.19        digest_0.6.31       
 [13] htmltools_0.5.4      fansi_1.0.3          magrittr_2.0.3       checkmate_2.1.0     
 [17] DHARMa_0.4.6         googlesheets4_1.0.1  tzdb_0.3.0           globals_0.16.1      
 [21] modelr_0.1.9         RcppParallel_5.1.5   matrixStats_0.62.0   xts_0.12.2          
 [25] svglite_2.1.0        timechange_0.1.1     prettyunits_1.1.1    colorspace_2.0-3    
 [29] rvest_1.0.3          ggdist_3.2.0         haven_2.5.1          xfun_0.35           
 [33] callr_3.7.3          crayon_1.5.2         jsonlite_1.8.4       lme4_1.1-31         
 [37] zoo_1.8-11           glue_1.6.2           gtable_0.3.1         gargle_1.2.1        
 [41] webshot_0.5.4        V8_4.2.1             distributional_0.3.1 car_3.1-1           
 [45] pkgbuild_1.3.1       rstan_2.26.11        abind_1.4-5          scales_1.2.1        
 [49] mvtnorm_1.1-3        DBI_1.1.3            rstatix_0.7.0        miniUI_0.1.1.1      
 [53] isoband_0.2.6        viridisLite_0.4.1    xtable_1.8-4         diffobj_0.3.5       
 [57] stats4_4.1.2         StanHeaders_2.26.11  DT_0.26              htmlwidgets_1.6.0   
 [61] httr_1.4.4           threejs_0.3.3        arrayhelpers_1.1-0   posterior_1.3.1     
 [65] ellipsis_0.3.2       pkgconfig_2.0.3      loo_2.5.1            farver_2.1.1        
 [69] dbplyr_2.2.1         utf8_1.2.2           labeling_0.4.2       tidyselect_1.2.0    
 [73] rlang_1.0.6          reshape2_1.4.4       later_1.3.0          munsell_0.5.0       
 [77] cellranger_1.1.0     tools_4.1.2          cli_3.4.1            generics_0.1.3      
 [81] broom_1.0.1          ggridges_0.5.4       evaluate_0.19        fastmap_1.1.0       
 [85] processx_3.8.0       knitr_1.41           fs_1.5.2             nlme_3.1-161        
 [89] mime_0.12            xml2_1.3.3           compiler_4.1.2       shinythemes_1.2.0   
 [93] rstudioapi_0.14      curl_4.3.3           ggsignif_0.6.3       reprex_2.0.2        
 [97] stringi_1.7.8        ps_1.7.2             Brobdingnag_1.2-9    lattice_0.20-45     
[101] Matrix_1.5-3         nloptr_2.0.3         markdown_1.1         shinyjs_2.1.0       
[105] tensorA_0.36.2       vctrs_0.5.1          pillar_1.8.1         lifecycle_1.0.3     
[109] bridgesampling_1.1-2 cowplot_1.1.1        httpuv_1.6.6         R6_2.5.1            
[113] promises_1.2.0.1     renv_0.16.0          parallelly_1.32.1    codetools_0.2-18    
[117] boot_1.3-28.1        colourpicker_1.1.1   MASS_7.3-58.1        gtools_3.9.4        
[121] assertthat_0.2.1     withr_2.5.0          shinystan_2.6.0      mgcv_1.8-41         
[125] parallel_4.1.2       hms_1.1.2            grid_4.1.2           coda_0.19-4         
[129] minqa_1.2.5          rmarkdown_2.19       carData_3.0-5        googledrive_2.0.0   
[133] shiny_1.7.1          lubridate_1.9.0      base64enc_0.1-3      dygraphs_1.1.1.6    
Bürkner, Paul-Christian. 2017. “Brms: An r Package for Bayesian Multilevel Models Using Stan.” Journal Article. 2017 80 (1): 28. https://doi.org/10.18637/jss.v080.i01.
Gelman, Andrew, John B. Carlin, Hal S. Stern, David B. Dunson, Aki Vehtari, and Donald B. Rubin. 2014. Bayesian Data Analysis. Book. 4th ed. New York: CRC Press.
Gelman, Andrew, Jennifer Hill, and Aki. Vehtari. 2020. Regression and Other Stories: Analytical Methods for Social Research. Book. 1st ed. Cambridge: CRC Press.
Link, William A., and Richard J. Barker. 2010. Bayesian Inference: With Ecological Applications. Book. 1st ed. Boston: Academic Press.
McElreath, Richard. 2020. Statistical Rethinking: A Bayesian Course with Examples in r and Stan. Book. 2nd ed. Boca Raton: CRC Press.
Merkle, Edgar C., Ellen Fitzsimmons, James Uanhoro, and Ben Goodrich. 2021. “Efficient Bayesian Structural Equation Modeling in Stan.” Journal Article. Journal of Statistical Software 100 (6): 1–22. https://doi.org/https://doi.org/10.18637/jss.v100.i06.
Merkle, Edgar C., and Yves Rosseel. 2018. “Blavaan: Bayesian Structural Equation Models via Parameter Expansion.” Journal Article. Journal of Statistical Software 85 (4): 1–30. https://doi.org/https://doi.org/10.18637/jss.v085.i04.
Poggiato, Giovanni, Tamara Munkemuller, Daria Bystrova, Julyan Arbel, James S. Clark, and Wilfried Thuiller. 2021. “On the Interpretations of Joint Modeling in Community Ecology.” Journal Article. Trends in Ecology & Evolution 36 (5): 391–401. https://doi.org/https://doi.org/10.1016/j.tree.2021.01.002.
R Core Team. 2021. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.
Team, Stan Development. 2018a. “RStan: The r Interface to Stan.” Journal Article. http://mc-stan.org.
———. 2018b. “Stan Modeling Language Users Guide and Reference Manual, Version 2.18.0.” Journal Article. http://mc-stan.org.
———. 2018c. “The Stan Core Library, Version 2.18.0.” Journal Article. http://mc-stan.org.
Warton, David I., Guillame F. Blanchet, Robert B. O’Hara, Otso Ovaskainen, Sara Taskinen, Steven C. Walker, and Francis K. C. Hui. 2015. “So Many Variables: Joint Modeling in Community Ecology.” Journal Article. Trends in Ecology & Evolution 30 (12): 766–79. https://doi.org/https://doi.org/10.1016/j.tree.2015.09.007.
Webb, Jackie R., Nicole M. Hayes, Gavin L. Simpson, Peter R. Leavitt, Helen M. Baulch, and Kerri Finlay. 2019. “Widespread Nitrous Oxide Undersaturation in Farm Waterbodies Creates an Unexpected Greenhouse Gas Sink.” Journal Article. Proceedings of the National Academy of Sciences 116 (20): 9814–19. https://doi.org/10.1073/pnas.1820389116.
Zachmann, Luke J., Erin M. Borgman, Dana L. Witwicki, Megan C. Swan, Cheryl McIntyre, and N. Thompson Hobbs. 2022. “Bayesian Models for Analysis of Inventory and Monitoring Data with Non-Ignorable Missingness.” Journal Article. Journal of Agricultural, Biological and Environmental Statistics 27: 125–48. https://doi.org/https://doi.org/10.1007/s13253-021-00473-z.
LS0tDQp0aXRsZTogIkJheWVzaWFuIG1vZGVscyBmb3IgTkxBIDIwMTcgJE5fMk8kIHN1cnZleSBkYXRhIg0KYXV0aG9yOiAiUm95IE1hcnRpbiwgSmFrZSBCZWF1bGlldSwgTWljaGFlbCBNY01hbnVzIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6ICc0Jw0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBmb250X3NpemU6IDE0DQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogc2ltcGxleA0KYmlibGlvZ3JhcGh5OiBSV01fRW5kbm90ZV9MaWJyYXJ5LmJpYg0KbGluay1jaXRhdGlvbnM6IHllcw0KZWRpdG9yX29wdGlvbnM6DQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7ciBiZWdpbiwgZXZhbD1UUlVFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShnZ3B1YnIpDQpsaWJyYXJ5KG1vbWVudHMpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGdnRXh0cmEpDQpsaWJyYXJ5KGdyaWRFeHRyYSkNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkoZ2dyZXBlbCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkodGlkeXIpDQpsaWJyYXJ5KGZ1dHVyZSkNCmxpYnJhcnkoZm9yZWFjaCkNCmxpYnJhcnkoaXRlcnRvb2xzKQ0KbGlicmFyeShiYXllc3Bsb3QpDQpsaWJyYXJ5KHRpZHliYXllcykNCmxpYnJhcnkoYnJtcykNCg0Kb3B0aW9ucyhtYy5jb3JlcyA9IHBhcmFsbGVsOjpkZXRlY3RDb3Jlcyhsb2dpY2FsID0gRkFMU0UpKQ0Kb3B0aW9ucyggbWF4LnByaW50ID0gMTAwMCApDQoNCiMgSWRlbnRpZnkgbG9jYWwgcGF0aCBmb3IgZWFjaCB1c2VyDQpsb2NhbFBhdGggPC0gU3lzLmdldGVudigiVVNFUlBST0ZJTEUiKQ0KDQojIERlZmluZSBoZWxwZXIgZnVuY3Rpb25zDQojIHN0YW5kYXJkaXplZCBmb3JtYXR0aW5nIGZvciBjb2x1bW4gbmFtZXMNCnRvRVBBIDwtIGZ1bmN0aW9uKFgxKXsNCiAgbmFtZXMoWDEpID0gdG9sb3dlcihuYW1lcyhYMSkpDQogIG5hbWVzKFgxKSA9IGdzdWIocGF0dGVybiA9IGMoIlxcKHwgfCN8KXwvfC18XFwrfDp8XyIpLCByZXBsYWNlbWVudCA9ICIuIiwgeCA9IG5hbWVzKFgxKSkNCiAgWDENCn0NCg0KIyBzdGF0OiBza2V3IA0Kc2tldyA8LSBmdW5jdGlvbih4KSB7DQogIHhkZXYgPC0geCAtIG1lYW4oeCkNCiAgbiA8LSBsZW5ndGgoeCkNCiAgciA8LSBzdW0oeGRldl4zKSAvIHN1bSh4ZGV2XjIpXjEuNQ0KICByZXR1cm4ociAqIHNxcnQobikgKiAoMSAtIDEvbileMS41KQ0KfQ0KDQojIGZ1bmN0aW9uIGZvciBESEFSTWEgcmVzaWR1YWwgYW5hbHlzaXMNCmNoZWNrX2JybXMgPC0gZnVuY3Rpb24obW9kZWwsICAgICAgICAgICAgICMgYnJtcyBtb2RlbA0KICAgICAgICAgICAgICAgICAgICAgICBpbnRlZ2VyID0gRkFMU0UsICAgIyBpbnRlZ2VyIHJlc3BvbnNlPyAoVFJVRS9GQUxTRSkNCiAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IFRSVUUsICAgICAgICMgbWFrZSBwbG90Pw0KICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgLi4uICAgICAgICAgICAgICAgICMgZnVydGhlciBhcmd1bWVudHMgZm9yIERIQVJNYTo6cGxvdFJlc2lkdWFscyANCikgew0KICANCiAgbWRhdGEgPC0gYnJtczo6c3RhbmRhdGEobW9kZWwpDQogIGlmKCEiWSIgJWluJSBuYW1lcyhtZGF0YSkpDQogICAgb1Jlc3AgPC0gbWRhdGFbW3Bhc3RlMCgiWV8iLCByZXNwKV1dDQogIGVsc2UNCiAgICBvUmVzcCA8LSBtZGF0YVtbIlkiXV0NCiAgIyAgc3RvcCgiQ2Fubm90IGV4dHJhY3QgdGhlIHJlcXVpcmVkIGluZm9ybWF0aW9uIGZyb20gdGhpcyBicm1zIG1vZGVsIikNCiAgDQogIGRoYXJtYS5vYmogPC0gREhBUk1hOjpjcmVhdGVESEFSTWEoDQogICAgc2ltdWxhdGVkUmVzcG9uc2UgPSB0KGJybXM6OnBvc3Rlcmlvcl9wcmVkaWN0KG1vZGVsLCByZXNwID0gcmVzcCwgbmRyYXdzID0gMTAwMCkpLA0KICAgIG9ic2VydmVkUmVzcG9uc2UgPSBvUmVzcCwgDQogICAgZml0dGVkUHJlZGljdGVkUmVzcG9uc2UgPSBhcHBseSgNCiAgICAgIHQoYnJtczo6cG9zdGVyaW9yX2VwcmVkKG1vZGVsLCByZXNwID0gcmVzcCwgbmRyYXdzID0gMTAwMCwgcmUuZm9ybSA9IE5BKSksDQogICAgICAxLA0KICAgICAgbWVkaWFuKSwNCiAgICBpbnRlZ2VyUmVzcG9uc2UgPSBpbnRlZ2VyKQ0KICANCiAgaWYgKGlzVFJVRShwbG90KSkgew0KICAgIHBsb3QoZGhhcm1hLm9iaiwgLi4uKQ0KICB9DQogIA0KICBpbnZpc2libGUoZGhhcm1hLm9iaikNCiAgDQp9DQpgYGANCg0KIyBSYXRpb25hbGUgYW5kIE9iamVjdGl2ZXMNClRoaXMgZG9jdW1lbnQgZGV0YWlscyB0aGUgbW9kZWxpbmcgd29ya2Zsb3cgaW1wbGVtZW50ZWQgZm9yIGVzdGltYXRpbmcgZGlzc29sdmVkIGFuZCBlcXVpbGlicml1bSBOMk8gY29uY2VudHJhdGlvbnMgYW5kIHNhdHVyYXRpb24gcmF0aW9zIHVzaW5nIHRoZSAyMDE3IE5hdGlvbiBMYWtlcyBBc3Nlc3NtZW50IChOTEEpIHN1cnZleSBkYXRhLiBUaGUgTkxBIHNhbXBsaW5nIHNpdGVzIHdlcmUgZGlzdHJpYnV0ZWQgYW1vbmcgdGhlIHRhcmdldCBwb3B1bGF0aW9uIG9mIFVTIGxha2VzIChpbiB0aGUgbG93ZXIgNDggc3RhdGVzKSBhY2NvcmRpbmcgdG8gYSBwcm9iYWJpbGlzdGljIHN1cnZleSBkZXNpZ24gd2l0aCBzYW1wbGVzIHN0cmF0aWZpZWQgYW1vbmcgY2F0ZWdvcmllcyBvZiBsYWtlIHN1cmZhY2UgYXJlYSwgV1NBOSBlY29yZWdpb24sIGFuZCBVUyBzdGF0ZSAoZXhjbHVkaW5nIEFLIGFuZCBISSkuIER1ZSB0byB0aGUgc3RyYXRpZmljYXRpb24gc2NoZW1lLCBzb21lIHR5cGVzIG9mIGxha2VzIGluIHRoZSBzYW1wbGUgcG9wdWxhdGlvbiB3ZXJlIGludGVudGlvbmFsbHkgb3Zlci1yZXByZXNlbnRlZCAoZS5nLiwgbGFyZ2UgbGFrZXMpIGFuZCBzb21lIHdlcmUgdW5kZXItcmVwcmVzZW50ZWQgKGUuZy4sIHNtYWxsIGxha2VzKSByZWxhdGl2ZSB0byB0aGUgdGFyZ2V0IHBvcHVsYXRpb24uIER1ZSB0byB0aGUgdW5lcXVhbCBwcm9iYWJpbGl0eSBkZXNpZ24sIGluZmVyZW5jZXMgZnJvbSB0aGUgc2FtcGxlIGhhZCB0byBiZSBhZGp1c3RlZCBmb3IgaW5mZXJlbmNlcyBvbiB0aGUgYnJvYWRlciBwb3B1bGF0aW9ucyBvZiBpbnRlcmVzdCAoZS5nLCBOYXRpb25hbC0sIHN0YXRlLSwgZWNvcmVnaW9uLSwgYW5kIHNpemUgY2xhc3Mtc3BlY2lmaWMgZXN0aW1hdGVzKS4gDQoNClRoZSBjb25jZXB0IG9mIHRoZSAiY29tcGxldGUgZGF0YSBsaWtlbGlob29kIiBpcyB1c2VmdWwgZm9yIGNvbmNlcHR1YWxpemluZyBiaWFzZXMgYXJpc2luZyBmcm9tIHNhbXBsaW5nIGRlc2lnbiBbQFphY2htYW5uX2V0YWxfMjAyMjsgQEdlbG1hbl9ldGFsXzIwMTQgQ2guIDg7IEBMaW5rX0Jhcmtlcl8yMDEwXS4gRm9yIHRoZSBOTEEgc3VydmV5IGRhdGEsIHRoZSBwb3B1bGF0aW9uIG9mIFVTIGxha2VzIGluIHRoZSBsb3dlciA0OCBzdGF0ZXMgbGFyZ2VyIHRoYW4gNCBoZWN0YXJlcyB3YXMgY29uc2lkZXJlZCB0aGUgY29tcGxldGUgZGF0YSBhbmQgdGhlIHByb2JhYmlsaXN0aWMgc2FtcGxlcyB3ZXJlIGNvbnNpZGVyZWQgYSBzdWJzZXQgb2YgdGhhdCBjb21wbGV0ZSBkYXRhLiBUaGUgcG9ydGlvbiBvZiBVUyBsYWtlcyBub3QgaW5jbHVkZWQgaW4gdGhlIHNhbXBsZSB3ZXJlIGNvbnNpZGVyZWQgIm1pc3NpbmciIGZyb20gdGhlIGNvbXBsZXRlIGRhdGEgX25vdF8gYXQgcmFuZG9tLCBidXQgY29uZGl0aW9uYWwgb24gdGhlIHByZS1zcGVjaWZpZWQgZGVzaWduIChzdHJhdGlmaWNhdGlvbikgdmFyaWFibGVzLiBUaGlzIG5vbi1yYW5kb20gbWlzc2luZ25lc3Mgd2FzIG5vdCBpZ25vcmFibGUgZm9yIHRoZSBwdXJwb3NlIG9mIG1ha2luZyBpbmZlcmVuY2VzIGZyb20gdGhlIHNhbXBsZSB0byB0aGUgdGFyZ2V0IHBvcHVsYXRpb24uIEluIGEgbW9kZWwtYmFzZWQgZnJhbWV3b3JrLCBob3dldmVyLCBpbmNsdWRpbmcgdGhlIGRlc2lnbiBwYXJhbWV0ZXJzIGFzIHByZWRpY3RvcnMgaW4gYSByZWdyZXNzaW9uIG1vZGVsIGlzIG9uZSB3YXkgdG8gYWRqdXN0IGZvciB0aGUgbWlzc2luZ25lc3MuIEZvciBhIHRob3JvdWdoIGFuZCByZWNlbnQgdHJlYXRtZW50IG9mIHRoaXMgY29uY2VwdCBpbiB0aGUgY29udGV4dCBvZiBuYXRpb25hbCBzdXJ2ZXlzIG9mIGVudmlyb25tZW50YWwgcmVzb3VyY2VzLCByZWZlciB0byBbQFphY2htYW5uX2V0YWxfMjAyMl0uIFRoaXMgY29uY2VwdCBpcyBhIGtleSBtb3RpdmF0b3IgZm9yIHRoZSBpbmNyZWFzaW5nbHkgcG9wdWxhciBtdWxpdGlsZXZlbCByZWdyZXNzaW9uIHdpdGggcG9zdHN0cmF0aWZpY2F0aW9uIChNUlApIGFwcHJvYWNoIHRvIG1vZGVsLWJhc2VkIGluZmVyZW5jZSBbQEdlbG1hbl9ldGFsXzIwMTQ7IEdlbG1hbnRfZXRhbF8yMDIwIENoLiAxN10uDQoNClRoZSBmb2xsb3dpbmcgd29ya2Zsb3cgaWxsdXN0cmF0ZXMgb3VyIG1vZGVsLWJhc2VkIGFwcHJvYWNoLCBiYXNlZCBsYXJnZWx5IG9uIHRoZSBsb2dpYyBvZiBNUlAsIGJ1dCB3aXRoIGFuIGVsYWJvcmF0aW9uIG9uIHRoZSBwb3N0c3RyYXRpZmljYXRpb24gc3RlcCB0byBlbmFibGUgZXZlbnR1YWwgZXN0aW1hdGVzIG9mIHRvdGFsIGdhcyBmbHV4IGF0IHRoZSBwb3B1bGF0aW9uIGxldmVsLCB3aGljaCByZXF1aXJlZCBzY2FsaW5nIHVwIGZyb20gbGFrZS1sZXZlbCBlc3RpbWF0ZXMuIFRoZSB0eXBpY2FsIE1SUCBwcm9jZXNzIGlzIGNhcnJpZWQgb3V0IGluIHR3byBzdGVwcy4gVGhlIGZpcnN0IHN0ZXAgaXMgdG8gZml0IHJlZ3Jlc3Npb24gbW9kZWxzIGZvciB0aGUgcmVzcG9uc2UgdmFyaWFibGVzIG9mIGludGVyZXN0IChlLmcuLCBkaXNzb2x2ZWQgTjJPLCBlcXVpbGlicml1bSBOMk8pIGNvbmRpdGlvbmFsIG9uIHRoZSBzdXJ2ZXkgZGVzaWduIHZhcmlhYmxlcyDilLwoaS5lLiwgZWNvcmVnaW9uLCBzdGF0ZSwgbGFrZSBzaXplKS4gVGhlIHNlY29uZCBzdGVwIGlzIHBvc3Qtc3RyYXRmaWNhdGlvbiwgd2hlcmVpbiB0aGUgcG9zdGVyaW9yIHBhcmFtZXRlciBlc3RpbWF0ZXMgZnJvbSB0aGUgcmVncmVzc2lvbiBtb2RlbCBmb3IgdGhlIHNhbXBsZSBwb3B1bGF0aW9uIGFyZSB3ZWlnaHRlZCBiYXNlZCBvbiB0aGVpciBrbm93biBvciBhc3N1bWVkIGRpc3RyaWJ1dGlvbiBpbiB0aGUgcG9wdWxhdGlvbiBvZiBpbnRlcmVzdCBbaS5lLiwgcG9zdC1zdHJhdGlmaWNhdGlvbiB0YWJsZTsgQEdlbG1hbl9ldGFsXzIwMjAgQ2guIDE3XS4gVGhlIHBvc3RzdHJhdGlmaWNhdGlvbiB0YWJsZSBpbiBvdXIgY2FzZSwgZm9yIGV4YW1wbGUsIHdvdWxkIGJlIGEgcG9wdWxhdGlvbiBzdW1tYXJ5IG9mIGxha2VzIGFtb25nIHRoZSBkZXNpZ24gdmFyaWFibGVzOiBlY29yZWdpb24sIHN0YXRlLCBhbmQgc2l6ZSBjYXRlZ29yeS4gSG93ZXZlciwgYmVjYXVzZSB3ZSBldmVudHVhbGx5IG5lZWRlZCBsYWtlLWxldmVsIGVzdG1hdGVzLCBpbnN0ZWFkIG9mIHByZWRpY3RpbmcgdG8gYSBwb3N0cmF0aWZpY2F0aW9uIHRhYmxlLCB3ZSBwcmVkaWN0ZWQgdG8gZWFjaCBpbmRpdmlkdWFsIGxha2UgaW4gdGhlIHBvcHVsYXRpb24gb2YgaW50ZXJlc3QuIFRoaXMgbWVhbnQgcHJlZGljdGluZyB0byB0aGUgZnVsbCB0YXJnZXQgcG9wdWxhdGlvbiBvZiA0NjUsODk3IG5hdHVyYWwgYW5kIG1hbiBtYWRlIFVTIGxha2VzIGxhcmdlciB0aGFuIDQgaGVjdGFyZXMgaW4gdGhlIGxvd2VyIDQ4IHN0YXRlcy4gVGhlc2UgcHJlZGljdGlvbnMgd2VyZSBhc3N1bWVkIHJlbGV2YW50IHRvIGF2ZXJhZ2UgY29uZGl0aW9ucyBkdXJpbmcgdGhlICJpbmRleCBwZXJpb2QiIGZvciBlYWNoIGxha2UgaW4gMjAxNy4gRGV0YWlscyBhYm91dCB0aGUgc2FtcGxpbmcgZnJhbWUgYXMgd2VsbCBhcyB0aGUgdGFyZ2V0IHBvcHVsYXRpb24gYXJlIGZ1cnRoZXIgY2xhcmlmaWVkIGluIHRoZSB3b3JrYm9vayBiZWxvdyB3aXRoIGRhdGEgc3VtbWFyaWVzIGFuZCBjb2RlLiANCg0KRm9yIHRoZSByZWdyZXNzaW9ucywgd2UgdXNlZCBtdWx0aWxldmVsIG1vZGVscyBmaXQgaW4gYSBmdWxseSBCYXllc2lhbiBmYXNoaW9uIE11bHRpbGV2ZWwgbW9kZWxzIGFyZSB0aG91Z2h0IHRvIHdvcmsgd2VsbCBpbiB0aGlzIGNvbnRleHQgYmVjYXVzZSB0aGV5IHByb3ZpZGUgcmVndWxhcml6ZWQgZXN0aW1hdGVzIGFsb25nIHRoZSBkZXNpZ24gZ3JvdXBpbmdzLCB3aGljaCBjYW4gaW1wcm92ZSBvdXQtb2Ytc2FtcGxlIGluZmVyZW5jZXMgW0BNY0VscmVhdGhfMjAyMF0uIEluZmVyZW5jZXMgZm9yIGxha2UgdHlwZXMgdGhhdCBtYXkgYmUgbWlzc2luZyBmcm9tIHRoZSBzYW1wbGUsIGJ1dCBhcmUgcGFydCBvZiB0aGUgcG9wdWxhdGlvbiBvZiBpbnRlcmVzdCBhcmUgYWxzbyBzdHJhaWdodGZvcndhcmQgdXNpbmcgdGhpcyBhcHByb2FjaCBbQEdlbG1hbl9ldGFsXzIwMjAgQ2guIDE3OyBATWNFbHJlYXRoXzIwMjBdLiBNb3JlIGluZm9ybWF0aW9uIHRoZXNlIG1vZGVscywgdGhlaXIgc3BlY2lmaWMgcGFyYW1ldGVycywgUiBjb2RlLCBmaXQgZXZhbHVhdGlvbnMsIGFuZCByZXN1bHRpbmcgaW5mZXJlbmNlcyBhcmUgcHJlc2VudGVkIGluIHRoaXMgZG9jdW1lbnQuDQoNClRoZSBvdmVycmlkaW5nIG9iamVjdGl2ZSBvZiB0aGUgbW9kZWxpbmcgZWZmb3J0IHdhcyB0byBwcm92aWRlIHBvcHVsYXRpb24gbGV2ZWwgZXN0aW1hdGVzIGZvciAoMSkgZGlzc29sdmVkIGFuZCBlcXVpbGlicml1bSBOMk8gY29uY2VudHJhdGlvbnM7ICgyKSB0aGUgTjJPIHNhdHVyYXRpb24gcmF0aW8gKGkuZS4sIGRpc3NvbHZlZCBOMk8vZXF1aWxpYnJpdW0gTjJPKTsgYW5kICgzKSB0aGUgcHJvcG9ydGlvbiBvZiB1bmRlci1zYXR1cmF0ZWQgd2F0ZXIgYm9kaWVzIChpLmUuLCBzYXR1cmF0aW9uIHJhdGlvIDwgMSkuIFRoZSBlc3RpbWF0ZXMgd291bGQgYWxzbyBiZSB1c2VkIHRvIGxhdGVyIGVzdGltYXRlIHRoZSB0b3RhbCBmbHV4IG9mIE4yTyBnYXMgYXR0cmlidXRhYmxlIHRvIHRoZSB0YXJnZXQgcG9wdWxhdGlvbiBvZiBsYWtlcyBvdmVyIHRoZSBpbmRleCBwZXJpb2QuIFRoZSBzYXR1cmF0aW9uIHJhdGlvIGVzdGltYXRlcyB3ZXJlIGNhbGN1bGF0ZWQgYXMgYSBkZXJpdmVkIHF1YW50aXR5IGJhc2VkIG9uIHRoZSByYXRpbyBvZiBtb2RlbGVkIGRpc3NvbHZlZCB0byBlcXVpbGlicml1bSBOMk8uIEJlY2F1c2UgZGlzc29sdmVkIGFuZCBlcXVpbGlicml1bSBOMk8gd2VyZSBvYnNlcnZlZCBvbiB0aGUgc2FtZSBzYW1wbGUgdW5pdHMgKGxha2Ugc2l0ZXMpLCB3ZSBkZXZlbG9wZWQgbW9kZWxzIGZvciBlc3RpbWF0aW5nIHRoZWlyIGpvaW50IGRpc3RyaWJ1dGlvbi4gVGhlIHJlc3BvbnNlIHZhcmlhYmxlIGluIHRoZSBtb2RlbHMgd2FzLCB0aGVyZWZvcmUsIG11bHRpdmFyaWF0ZSB0byBhY2NvdW50IGZvciBwb3RlbnRpYWwgc3RhdGlzdGljYWwgZGVwZW5kZW5jaWVzIGJldHdlZW4gZGlzc29sdmVkIGFuZCBlcXVpbGlicml1bSBOMk8gZHVlIHRvLCBmb3IgZXhhbXBsZSwgY29tbW9uIGRlcGVuZGVuY2llcyBvbiBnZW9ncmFwaHkuIEFsdGhvdWdoIHBvaW50IHByZWRpY3Rpb25zIG9mIHRoZSBtZWFuIG1hcmdpbmFsIHByb2JhYmlsaXRpZXMgZnJvbSBzZXBhcmF0ZSBtb2RlbHMgY291bGQgYmUgY29tcGFyYWJsZSwgYSBqb2ludCBtb2RlbCBhbGxvd2luZyBjb3JyZWxhdGVkIG9ic2VydmF0aW9uLWxldmVsIGVycm9ycyAoaS5lLiwgcmVzaWR1YWxzKSB3YXMgZXhwZWN0ZWQgdG8gYmV0dGVyIGNhcHR1cmUgdW5jZXJ0YWludHkgYW5kIHBvdGVudGlhbGx5IGltcHJvdmUgb3V0LW9mLXNhbXBsZSBwcmVkaWN0aW9ucywgc2hvdWxkIHRoZSB2YXJpYWJsZXMgYmUgY29uZGl0aW9uYWxseSBjb3JyZWxhdGVkIFtAV2FydG9uX2V0YWxfMjAxNTsgQFBvZ2dpYXRvX2V0YWxfMjAyMV0uIEFsbCBvZiB0aGUgbW9kZWxzIGZpdCB3ZXJlIGNvbnN0cnVjdGVkIHVzaW5nIHRoZSBgYnJtc2AgcGFja2FnZSBbQEJ1cmtuZXJfMjAxN10gaW4gYFJgIFtAUl9Db3JlX1RlYW1fMjAyMV0gYXMgYW4gaW50ZXJmYWNlIHRvIFN0YW4sIGEgc29mdHdhcmUgcGFja2FnZSBmb3IgZml0dGluZyBmdWxseSBCYXllc2lhbiBtb2RlbHMgdmlhIEhhbWlsdG9uaWFuIE1vbnRlIENhcmxvIFtITUM7IEBTdGFuX0RldmVsb3BtZW50X1RlYW1fMjAxOF9hOyBAU3Rhbl9EZXZlbG9wbWVudF9UZWFtXzIwMThfYjsgQFN0YW5fRGV2ZWxvcG1lbnRfVGVhbV8yMDE4X2NdLg0KDQojIERhdGENCkFzIGV4cGxhaW5lZCBpbiBhIHByZXZpb3VzIGRhdGEgbXVuZ2luZyBkb2N1bWVudCBkb2N1bWVudA0KKGh0dHBzOi8vZ2l0aHViLmNvbS9VU0VQQS9EaXNzb2x2ZWRHYXNObGEvYmxvYi9tYXN0ZXIvc2NyaXB0cy9kZ0luZGljYXRvckFuYWx5c2lzLmh0bWwpLCBkdXBsaWNhdGUgZGlzc29sdmVkIGdhcyBzYW1wbGVzIHdlcmUgY29sbGVjdGVkIGF0IGEgZGVwdGggb2YgfjAuMW0gYXQgZGVzaWduYXRlZCBpbmRleCBzaXRlcyBkaXN0cmlidXRlZCBhY3Jvc3MgMTA5MSBsYWtlcyBuYXRpb253aWRlLCBvZiB3aGljaCA5NSB3ZXJlIHNhbXBsZWQgdHdpY2UgYXMgcmVwZWF0IHZpc2l0cy4gVGhpcyByYW5kb21seSBzZWxlY3RlZCBzdWJzZXQgb2YgcmV2aXNpdCBzaXRlcyB3YXMgdXNlZCBhcyBhIHRlc3Qgc2V0IGZvciBhc3Nlc3NpbmcgbW9kZWwgZml0IGFuZCBvdXQtb2Ytc2FtcGxlIHBlcmZvcm1hbmNlLiANCg0KR2FzIHNhbXBsZXMgd2VyZSBhbmFseXplZCB2aWEgZ2FzIGNocm9tb3RvZ3JhcGh5IGFuZCBjb25jZW50cmF0aW9ucyB3ZXJlIHJlY29yZGVkIHRvIHRoZSBuZWFyZXN0IDAuMDAxIG5tb2wvTC4gVGhlIHNhbXBsZXMgd2VyZSBjb2xsZWN0ZWQgdW5kZXIgYSBzdHJhdGlmaWVkLCB1bmVxdWFsIHByb2JhYmlsaXR5IGRlc2lnbiBhbmQgZWFjaCBnYXMgb2JzZXJ2YXRpb24gd2FzIGluZGV4ZWQgdG8gYW4gaW5kaXZpZHVhbCBsYWtlIHNlbGVjdGVkIHdpdGggdW5lcXVhbCBwcm9iYWJpbGl0eSBmcm9tIDUgZGlmZmVyZW50IGxha2Ugc2l6ZSBjYXRlZ29yaWVzLCAkaiBcaW4gaj0xLC4uLixKID0gNSQsIGFjY29yZGluZyB0byBzdXJmYWNlIGFyZWEgKGhhKSwgYW5kIGZyb20gd2l0aGluIGEgc3RhdGUsICRrIFxpbiBrPTEsLi4uLEsgPSA0OCQsIHNpdHVhdGVkIHdpdGhpbiBhbiBhZ2dyZWdhdGVkLCBXU0E5IG9yIE9tZXJuaWsgZWNvcmVnaW9uLCAkbCBcaW4gbD0xLC4uLixMID0gOSQuIEFsbCA5IFdTQTkgZWNvcmVnaW9ucyB3ZXJlIHJlcHJlc2VudGVkIGluIHRoZSBzYW1wbGUsIGluY2x1ZGluZyBYZXJpYyAoWEVSKSwgV2VzdGVybiBNb3VudGFpbiAoV01UKSwgIE5vcnRoZXJuIFBsYWlucyAoTlBMKSwgU291dGhlcm4gUGxhaW5zIChTUEwpLCBUZW1wZXJhdGUgUGxhaW5zIChUUEwpLCBDb2FzdGFsIFBsYWlucyAoQ1BMKSwgVXBwZXIgTWlkd2VzdCAoVU1XKSwgTm9ydGhlcm4gQXBwYWxhY2hpYW4gKE5BUCksIGFuZCBTb3V0aGVybiBBcHBhbGFjaGlhbiAoU0FQKSByZWdpb25zLiBBcyBzaG93biBiZWxvdywgdGhlIGRhdGEgZnJvbSB0aGUgaW5pdGlhbCBhbmQgcmV2aXNpdCBzYW1wbGVzIHdlcmUgc2VwYXJhdGVseSBjb21waWxlZCBpbnRvIGRhdGEgZnJhbWUgb2JqZWN0cyBpbiAkXHRleHRiZntSfSQsIHdpdGggJG49OTg0JCBhbmQgJG49OTUkIHJvd3MsIHJlc3BlY3RpdmVseSwgb2YgZ2FzIG9ic2VydmF0aW9ucyBpbmRleGVkIHRvIHRoZSBzdXJ2ZXkgZGVzaWduIHZhcmlhYmxlcyBhbmQgc2V2ZXJhbCBwb3RlbnRpYWxseSByZWxldmFudCBjb3ZhcmlhdGVzLiANCg0KIyMgSW1wb3J0DQpUaGUgZ2FzIGRhdGEgYW5kIGNvdmFyaWF0ZXMgd2VyZSBwcmV2aW91c2x5IGRlc2NyaWJlZCBhbmQgbXVuZ2VkIGF0IA0KaHR0cHM6Ly9naXRodWIuY29tL1VTRVBBL0Rpc3NvbHZlZEdhc05sYS9ibG9iL21hc3Rlci9zY3JpcHRzL2RhdGFNdW5nZS5odG1sLiBUaGF0IGRhdGFzZXQgd2FzIGltcG9ydGVkIGJlbG93LiANCmBgYHtyIGltcG9ydF9kYXRhLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCBmaWxlID0gcGFzdGUwKCBsb2NhbFBhdGgsDQogICAgICAgICAgICAgICIvRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS8iLA0KICAgICAgICAgICAgICAiT1JEIE5MQTE3IERpc3NvbHZlZCBHYXMgLSBEb2N1bWVudHMvIiwNCiAgICAgICAgICAgICAgImlucHV0RGF0YS9kZy4yMDIxLTAyLTAxLlJEYXRhIikNCiAgICAgICkNCg0Kc2F2ZShkZywgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZy5yZGEiKSANCmBgYA0KDQpGcm9tIHRoZSBpbXBvcnRlZCBkYXRhc2V0LCBhIG5ldyBkYXRhIGZyYW1lIGZvciBtb2RlbGluZyB3YXMgY29uc3RydWN0ZWQgZnJvbSB0aGUgb3JpZ2luYWwgZmlsZSBpbmNsdWRpbmcgb25seSB0aGUgdmFyaWFibGVzIG9mIGludGVyZXN0OiAoMSkgdGhlIE4yTyBnYXMgb2JzZXJ2YXRpb25zOyAoMikgdGhlIHN1cnZleSBkZXNpZ24gdmFyaWFibGVzIGluZGV4ZWQgdG8gdGhvc2Ugb2JzZXJ2YXRpb25zOyBhbmQgKDMpIGFkZGl0aW9uYWwgY292YXJpYXRlcyBjb25zaWRlcmVkIHBvdGVudGlhbGx5IHVzZWZ1bCBmb3IgaW1wcm92aW5nIHRoZSBmaXQgb2YgdGhlIG1vZGVsLiBUaGUgZGF0YSBmcmFtZSBiZWxvdyBleGNsdWRlZCB0aGUgc2Vjb25kLXZpc2l0IG9ic2VydmF0aW9ucywgd2hpY2ggd291bGQgbGF0ZXIgYmUgdXNlZCBmb3IgbW9kZWwgY2hlY2tpbmcuIFNvbWUgdmFyaWFibGVzIGZyb20gdGhlIGltcG9ydGVkIGRhdGEgd2VyZSByZW5hbWVkIGZvciBjb252ZW5pZW5jZS4gSW4gYWRkaXRpb24sIHRoZSBOTzMgY292YXJpYXRlIHdhcyByb3VuZGVkIGFjY29yZGluZyB0byB0aGUgZG9jdW1lbnRlZCBtZWFzdXJlbWVudCBwcmVjaXNpb24uIEFuIGFsdGVybmF0aXZlIHZlcnNpb24gb2YgdGhlIE5PMyBjb3ZhcmlhdGUgd2FzIGFsc28gY3JlYXRlZCBpbiB0aGlzIHN0ZXAgYnkgbG9nLXRyYW5zZm9ybWluZyBhbmQgcmUtY29kaW5nIGl0IGFzIGFuIG9yZGVyZWQgZmFjdG9yIHdpdGggZml2ZSBsZXZlbHMgYXQgaGFuZC1kcmF3biBjdXQgcG9pbnRzLiBUaGUgbGVmdC1tb3N0IGN1dCBwb2ludCBzZXBhcmF0ZWQgb2JzZXJ2YXRpb25zIGJlbG93IHRoZSBkZXRlY3Rpb24gbGltaXQgZnJvbSB0aGUgY29tcGxldGVseSBvYnNlcnZlZCBzYW1wbGVzLiBUaGUgcmVtYWluaW5nIGN1dCBwb2ludHMgaW4gdGhlIHBvc2l0aXZlIGRpcmVjdGlvbiB3ZXJlIGRyYXduIGF0IGFwcHJveGltYXRlbHkgZXF1YWwgZGlzdGFuY2VzIGFsb25nIHRoZSBsb2cgc2NhbGUuIEZpbmFsbHksIGl0IHNob3VsZCBiZSBub3RlZCB0aGF0IG9uZSBsYWtlIHRoYXQgd2FzIHNhbXBsZWQgd2FzIG1pc3NpbmcgaW5mb3JtYXRpb24gb24gdGhlIE4yTyBnYXMgbWVhc3VyZW1lbnRzIGFuZCBpdCB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBkYXRhIGZyYW1lLg0KYGBge3IgbW9kZWxfZGF0YSwgZWNobz1UUlVFLCBwYWdlZC5wcmludD1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGcucmRhIikNCg0KZGcgJT4lDQogIGZpbHRlcighaXMubmEoZGlzc29sdmVkLm4yby5ubW9sKSkgJT4lICMgMSBvYnMgd2l0aCBtaXNzaW5nIG1lYXN1cmVtZW50DQogIG5yb3coKSAjIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgYmVmb3JlIGZpbHRlcmluZw0KDQpkZl9tb2RlbCA8LSBkZyAlPiUNCiAgZmlsdGVyKCFpcy5uYShkaXNzb2x2ZWQubjJvLm5tb2wpKSAlPiUNCiAgZmlsdGVyKHNpdGV0eXBlID09ICJQUk9CIikgJT4lICMgcHJvYmFiaWxpdHkgc2FtcGxlcyBvbmx5DQogIGZpbHRlcih2aXNpdC5ubyA9PSAxKSAlPiUNCiAgbXV0YXRlKG4ybyA9IHJvdW5kKGRpc3NvbHZlZC5uMm8ubm1vbCwgMiksDQogICAgICAgICBuMm9fZXEgPSByb3VuZChzYXQubjJvLm5tb2wsIDIpLA0KICAgICAgICAgbjJvX3NhdCA9IG4yby5zYXQucmF0aW8sDQogICAgICAgICBuMm9fZW0gPSBlLm4yby5ubW9sLmQsDQogICAgICAgICBuMm9fZmx1eCA9IGYubjJvLm0uZCwNCiAgICAgICAgIFdTQTkgPSBmYWN0b3IoYWcuZWNvOSksDQogICAgICAgICBzdGF0ZSA9IGZhY3RvcihzdGF0ZS5hYmJbbWF0Y2goc3RhdGUubm0sIHN0YXRlLm5hbWUpXSksDQogICAgICAgICBhcmVhX2hhID0gYXJlYS5oYSwNCiAgICAgICAgIGxvZ19hcmVhID0gbG9nKGFyZWFfaGEpLA0KICAgICAgICAgY2hsYSA9IGNobGEucmVzdWx0LA0KICAgICAgICAgbG9nX2NobGEgPSBsb2coY2hsYSksDQogICAgICAgICBlbGV2ID0gZWxldmF0aW9uLA0KICAgICAgICAgbG9nX2VsZXYgPSBsb2coZWxldiArIDEpLA0KICAgICAgICAgZG9fc3VyZiA9IG8yLnN1cmYsDQogICAgICAgICBsb2dfZG8gPSBsb2coZG9fc3VyZiksDQogICAgICAgICBiZl9tYXggPSBtYXguYmYsDQogICAgICAgICBzcXJ0X2JmID0gc3FydChiZl9tYXgpLA0KICAgICAgICAgc2l6ZV9jYXQgPSByZWNvZGUoYXJlYS5jYXQ2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMSw0XSIgPSAibWluXzQiICwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMTAsMjBdIiA9ICIxMF8yMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiKDIwLDUwXSIgPSAiMjBfNTAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIig0LDEwXSIgPSAiNF8xMCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiPjUwIiA9ICI1MF9tYXgiKSkgJT4lDQogIG11dGF0ZShzaXplX2NhdCA9IGZhY3RvcihzaXplX2NhdCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIm1pbl80IiwgIjRfMTAiLCAiMTBfMjAiLCAiMjBfNTAiLCAiNTBfbWF4IiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQ0KICBtdXRhdGUobm8zID0gaWZlbHNlKG5pdHJhdGUubi5yZXN1bHQgPD0gMC4wMDA1LCAwLjAwMDUsIHJvdW5kKG5pdHJhdGUubi5yZXN1bHQsIDQpKSkgJT4lIyAxLzIgbWRsIDAuMDENCiAgbXV0YXRlKG5vM19jYXQgPSBjdXQobG9nKG5vMyksICMgY29udmVydCBubzMgdG8gb3JkZXJlZCBmYWN0b3Igd2l0aCA1IGxldmVscw0KICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIC03LjUsIC01LjUsIC0zLjUsIC0xLjUsIEluZiksDQogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9c2VxKDEsIDUsIDEpKSkgJT4lDQogIG11dGF0ZShubzNfY2F0ID0gZmFjdG9yKG5vM19jYXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHNlcSgxLCA1LCAxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUNCiAgbXV0YXRlKGRhdGUgPSBhcy5EYXRlKGRhdGUuY29sKSkgJT4lDQogIG11dGF0ZShqZGF0ZSA9IGFzLm51bWVyaWMoZm9ybWF0KGRhdGUsICIlaiIpKSkgJT4lIA0KICBtdXRhdGUobGF0ID0gbWFwLmxhdC5kZCwNCiAgICAgICAgIGxvbiA9IG1hcC5sb24uZGQpICU+JSAjIGxvbmdpdHVkZQ0KICBtdXRhdGUoc3VyZnRlbXAgPSBzdXJmdGVtcCwNCiAgICAgICAgIGxvZ19zdXJmdGVtcCA9IGxvZyhzdXJmdGVtcCkpICU+JSANCiAgc2VsZWN0KFdTQTksDQogICAgICAgICBzdGF0ZSwNCiAgICAgICAgIHNpemVfY2F0LA0KICAgICAgICAgc2l0ZS5pZCwNCiAgICAgICAgIGxhdCwNCiAgICAgICAgIGxvbiwNCiAgICAgICAgIGRhdGUsDQogICAgICAgICBqZGF0ZSwNCiAgICAgICAgIHN1cmZ0ZW1wLA0KICAgICAgICAgbG9nX3N1cmZ0ZW1wLA0KICAgICAgICAgYXJlYV9oYSwNCiAgICAgICAgIGxvZ19hcmVhLA0KICAgICAgICAgZWxldiwNCiAgICAgICAgIGxvZ19lbGV2LA0KICAgICAgICAgY2hsYSwNCiAgICAgICAgIGxvZ19jaGxhLA0KICAgICAgICAgZG9fc3VyZiwNCiAgICAgICAgIGxvZ19kbywNCiAgICAgICAgIGJmX21heCwNCiAgICAgICAgIHNxcnRfYmYsDQogICAgICAgICBuMm8sDQogICAgICAgICBuMm9fZXEsDQogICAgICAgICBubzMsDQogICAgICAgICBubzNfY2F0DQogICAgICAgICApDQoNCnNhdmUoZGZfbW9kZWwsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikgDQoNCm5yb3coZGZfbW9kZWwpICMgbnVtYmVyIG9mIG9icyBhZnRlciBmaWx0ZXJpbmcNCg0KcHJpbnQoZGZfbW9kZWwpDQpgYGANCg0KQSBzZWNvbmQgZGF0YWZyYW1lLCBpbmNsdWRpbmcgb25seSB0aGUgc2Vjb25kIHZpc2l0IG9ic2VydmF0aW9ucywgd2FzIGNvbnN0cnVjdGVkIGJlbG93LiBUaGVzZSBkYXRhIHdlcmUgbGF0ZXIgdXNlZCBhcyBhICJ0ZXN0IHNldCIgdG8gYXNzZXNzIHRoZSBvdXQtb2Ytc2FtcGxlIGZpdCBvZiB0aGUgbW9kZWwgZGV2ZWxvcGVkIG9uIHRoZSBmaXJzdC12aXNpdCBvciB0cmFpbmluZyBkYXRhLg0KYGBge3IgdGVzdF9kYXRhLCBlY2hvPVRSVUUsIHBhZ2VkLnByaW50PVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZy5yZGEiKQ0KDQojIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgYmVmb3JlIGZpbHRlcmluZyBwcm9iYWJpbGl0eSBzYW1wbGVzDQpkZyAlPiUNCiAgZmlsdGVyKCFpcy5uYShkaXNzb2x2ZWQubjJvLm5tb2wpKSAlPiUgIyByZW1vdmUgb2JzIHdpdGggbWlzc2luZyByZXNwb25zZSBtZWFzdXJlbWVudHMNCiAgbnJvdygpDQoNCmRmX3Rlc3QgPC0gZGcgJT4lDQogIGZpbHRlcighaXMubmEoZGlzc29sdmVkLm4yby5ubW9sKSkgJT4lDQogIGZpbHRlcihzaXRldHlwZSA9PSAiUFJPQiIpICU+JSAjIHByb2JhYmlsaXR5IHNhbXBsZXMgb25seQ0KICBmaWx0ZXIodmlzaXQubm8gPT0gMikgJT4lDQogIG11dGF0ZShuMm8gPSByb3VuZChkaXNzb2x2ZWQubjJvLm5tb2wsIDIpLA0KICAgICAgICAgbjJvX2VxID0gcm91bmQoc2F0Lm4yby5ubW9sLCAyKSwNCiAgICAgICAgIG4yb19zYXQgPSBuMm8uc2F0LnJhdGlvLA0KICAgICAgICAgbjJvX2VtID0gZS5uMm8ubm1vbC5kLA0KICAgICAgICAgbjJvX2ZsdXggPSBmLm4yby5tLmQsDQogICAgICAgICBXU0E5ID0gZmFjdG9yKGFnLmVjbzkpLA0KICAgICAgICAgc3RhdGUgPSBmYWN0b3Ioc3RhdGUuYWJiW21hdGNoKHN0YXRlLm5tLCBzdGF0ZS5uYW1lKV0pLA0KICAgICAgICAgYXJlYV9oYSA9IGFyZWEuaGEsDQogICAgICAgICBsb2dfYXJlYSA9IGxvZyhhcmVhX2hhKSwNCiAgICAgICAgIGNobGEgPSBjaGxhLnJlc3VsdCwNCiAgICAgICAgIGxvZ19jaGxhID0gbG9nKGNobGEpLA0KICAgICAgICAgZWxldiA9IGVsZXZhdGlvbiwNCiAgICAgICAgIGxvZ19lbGV2ID0gbG9nKGVsZXYgKyAxKSwNCiAgICAgICAgIGRvX3N1cmYgPSBvMi5zdXJmLA0KICAgICAgICAgbG9nX2RvID0gbG9nKGRvX3N1cmYpLA0KICAgICAgICAgYmZfbWF4ID0gbWF4LmJmLA0KICAgICAgICAgc3FydF9iZiA9IHNxcnQoYmZfbWF4KSwNCiAgICAgICAgIHNpemVfY2F0ID0gcmVjb2RlKGFyZWEuY2F0NiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiKDEsNF0iID0gIm1pbl80IiAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiKDEwLDIwXSIgPSAiMTBfMjAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIigyMCw1MF0iID0gIjIwXzUwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIoNCwxMF0iID0gIjRfMTAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIj41MCIgPSAiNTBfbWF4IikpICU+JQ0KICBtdXRhdGUoc2l6ZV9jYXQgPSBmYWN0b3Ioc2l6ZV9jYXQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJtaW5fNCIsICI0XzEwIiwgIjEwXzIwIiwgIjIwXzUwIiwgIjUwX21heCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUNCiAgbXV0YXRlKG5vMyA9IGlmZWxzZShuaXRyYXRlLm4ucmVzdWx0IDw9IDAuMDAwNSwgMC4wMDA1LCByb3VuZChuaXRyYXRlLm4ucmVzdWx0LCA0KSkpICU+JSMgMS8yIG1kbCAwLjAxDQogIG11dGF0ZShubzNfY2F0ID0gY3V0KGxvZyhubzMpLCAjIGNvbnZlcnQgbm8zIHRvIG9yZGVyZWQgZmFjdG9yIHdpdGggNSBsZXZlbHMNCiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygtSW5mLCAtNy41LCAtNS41LCAtMy41LCAtMS41LCBJbmYpLA0KICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPXNlcSgxLCA1LCAxKSkpICU+JQ0KICBtdXRhdGUobm8zX2NhdCA9IGZhY3RvcihubzNfY2F0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBzZXEoMSwgNSwgMSksDQogICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lDQogIG11dGF0ZShkYXRlID0gYXMuRGF0ZShkYXRlLmNvbCkpICU+JQ0KICBtdXRhdGUoamRhdGUgPSBhcy5udW1lcmljKGZvcm1hdChkYXRlLCAiJWoiKSkpICU+JSANCiAgbXV0YXRlKGxhdCA9IG1hcC5sYXQuZGQsDQogICAgICAgICBsb24gPSBtYXAubG9uLmRkKSAlPiUgIyBsb25naXR1ZGUNCiAgbXV0YXRlKHN1cmZ0ZW1wID0gc3VyZnRlbXAsDQogICAgICAgICBsb2dfc3VyZnRlbXAgPSBsb2coc3VyZnRlbXApKSAlPiUgDQogIHNlbGVjdChXU0E5LA0KICAgICAgICAgc3RhdGUsDQogICAgICAgICBzaXplX2NhdCwNCiAgICAgICAgIHNpdGUuaWQsDQogICAgICAgICBsYXQsDQogICAgICAgICBsb24sDQogICAgICAgICBkYXRlLA0KICAgICAgICAgamRhdGUsDQogICAgICAgICBzdXJmdGVtcCwNCiAgICAgICAgIGxvZ19zdXJmdGVtcCwNCiAgICAgICAgIGFyZWFfaGEsDQogICAgICAgICBsb2dfYXJlYSwNCiAgICAgICAgIGVsZXYsDQogICAgICAgICBsb2dfZWxldiwNCiAgICAgICAgIGNobGEsDQogICAgICAgICBsb2dfY2hsYSwNCiAgICAgICAgIGRvX3N1cmYsDQogICAgICAgICBsb2dfZG8sDQogICAgICAgICBiZl9tYXgsDQogICAgICAgICBzcXJ0X2JmLA0KICAgICAgICAgbjJvLA0KICAgICAgICAgbjJvX2VxLA0KICAgICAgICAgbm8zLA0KICAgICAgICAgbm8zX2NhdA0KICAgICAgICAgKQ0KDQpzYXZlKGRmX3Rlc3QsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfdGVzdC5yZGEiKSANCg0KbnJvdyhkZl90ZXN0KSAjIG51bWJlciBvZiBvYnMgYWZ0ZXIgZmlsdGVyaW5nIGZvciBwcm9iYWJpbGl0eSBzYW1wbGVzLCBmaXJzdCB2aXNpdHMsIGFuZCByZW1vdmluZyBvbmUgc2l0ZSBtaXNzaW5nIGVjb3JlZ2lvbiAoV1NBOSkgaW5mby4NCg0KcHJpbnQoZGZfdGVzdCkNCmBgYA0KDQojIyBUYXJnZXQgcG9wdWxhdGlvbg0KQmVsb3cuIHRoZSBOTEEgc2FtcGxpbmcgZnJhbWUgd2FzIGltcG9ydGVkIGFuZCB0aGVuIGZpbHRlcmVkIHRvIGluY2x1ZGUgb25seSB0aGUgdGFyZ2V0IHBvcHVsYXRpb24gb3Igc2FtcGxpbmcgZnJhbWUgZm9yIHRoaXMgcHJvamVjdC4NCmBgYHtyIGltcG9ydF9zYW1wbGVfZnJhbWUsIGVjaG89VFJVRX0NCmRmX3BvcCA8LSByZWFkLmNzdihmaWxlID0gcGFzdGUwKGxvY2FsUGF0aCwNCiAgICAgICAgICAgICAgIi9FbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpLyIsDQogICAgICAgICAgICAgICJPUkQgTkxBMTcgRGlzc29sdmVkIEdhcyAtIERvY3VtZW50cy8iLA0KICAgICAgICAgICAgICAiaW5wdXREYXRhL05MQV9TYW1wbGVfRnJhbWUuY3N2IiksIGhlYWRlciA9IFQpDQoNCnNmcmFtZSA8LSBkZl9wb3AgJT4lDQogIGZpbHRlcihubGExN19zZiAhPSAiRXhjbHVkZTIwMTciKSAlPiUNCiAgZmlsdGVyKG5sYTE3X3NmICE9ICJFeGNsdWRlMjAxN19JbmNsdWRlMjAxN05IIikgJT4lDQogIGZpbHRlcihzdGF0ZSAhPSAiREMiKSAlPiUNCiAgZmlsdGVyKHN0YXRlICE9ICJISSIpICU+JQ0KICBkcm9wbGV2ZWxzKCkgJT4lDQogIG11dGF0ZShXU0E5ID0gZmFjdG9yKGFnX2VjbzkpLA0KICAgICAgICAgV1NBOSA9IGZvcmNhdHM6OmZjdF9kcm9wKFdTQTkpLCAjIHJlbW92ZSBOQSBsZXZlbA0KICAgICAgICAgc3RhdGUgPSBmYWN0b3Ioc3RhdGUpLA0KICAgICAgICAgc2l6ZV9jYXQgPSBmYWN0b3IoYXJlYV9jYXQ2KSwNCiAgICAgICAgIGxhdCA9IGxhdF9kZDgzLA0KICAgICAgICAgbG9uID0gbG9uX2RkODMsDQogICAgICAgICBsb2dfYXJlYSA9IGxvZyhhcmVhX2hhKSwNCiAgICAgICAgIGVsZXYgPSBlbGV2YXRpb24sDQogICAgICAgICBsb2dfZWxldiA9IGlmZWxzZShlbGV2IDw9IDAsIDAsIGVsZXYpLCAjIGFzc3VtZWQgZWxldiA8IDAgdG8gYmUgZWxldiA9IDANCiAgICAgICAgIGxvZ19lbGV2ID0gbG9nKGxvZ19lbGV2ICsgMSkNCiAgICAgICAgICkgJT4lIA0KICBtdXRhdGUoc2l6ZV9jYXQgPSByZWNvZGUoc2l6ZV9jYXQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIigxLDRdIiA9ICJtaW5fNCIgLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIigxMCwyMF0iID0gIjEwXzIwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIoMjAsNTBdIiA9ICIyMF81MCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiKDQsMTBdIiA9ICI0XzEwIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICI+NTAiID0gIjUwX21heCIpKSAlPiUNCiAgbXV0YXRlKHNpemVfY2F0ID0gZmFjdG9yKHNpemVfY2F0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIm1pbl80IiwgIjRfMTAiLCAiMTBfMjAiLCAiMjBfNTAiLCAiNTBfbWF4IiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQ0KICBzZWxlY3QoV1NBOSwgc3RhdGUsIHNpemVfY2F0LCBsYXQsIGxvbiwgYXJlYV9oYSwgbG9nX2FyZWEsIGVsZXYsIGxvZ19lbGV2KQ0KDQpybShkZl9wb3ApDQoNCnNhdmUoc2ZyYW1lLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NmcmFtZS5yZGEiKSANCg0KcHJpbnQoc2ZyYW1lKQ0KYGBgDQoNClRoZSByZXN1bHRpbmcgdGFyZ2V0IHBvcHVsYXRpb24gYWJvdmUgaW5jbHVkZWQgYSB0b3RhbCBvZiA0NjUsODk3IHdhdGVyYm9kaWVzLg0KDQpDcm9zcyB0YWJ1bGF0aW9ucyBiZWxvdyBkZXNjcmliZSB0aGUgc3RydWN0dXJlIG9mIHRoZSB0YXJnZXQgcG9wdWxhdGlvbiB3aXRoIHJlc3BlY3QgdG8gdGhlIGRlc2lnbiB2YXJpYWJsZXMuIFRoZSBjcm9zcy10YWJ1bGF0aW9uIG1ha2VzIGl0IGNsZWFyIHRoYXQgZWFjaCBlY29yZWdpb24gZG9lcyBub3QgY29udGFpbiBlYWNoIHN0YXRlLiBUaGVyZWZvcmUsIGluIHRoZSBzdGF0aXN0aWNhbCBzZW5zZSwgc3RhdGVzIHdlcmUgbmVzdGVkIGluIGVjb3JlZ2lvbnMuDQpgYGB7ciBmcmFtZV9kaW1lbnNpb25zXzEsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NmcmFtZS5yZGEiKQ0KDQpzZnJhbWUgJT4lDQogIGdyb3VwX2J5KFdTQTksIHN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBzcHJlYWQoc3RhdGUsIG4pICU+JQ0KICBwcmludCgpDQpgYGANCg0KTGlrZXdpc2UsIGxha2Ugc2l6ZSBjYXRlZ29yeSB3YXMgbmVzdGVkIGluIHN0YXRlICh3aGljaCB3YXMgbmVzdGVkIGluIGVjb3JlZ2lvbikuIFRoYXQgaXMsIG5vdCBldmVyeSBlY29yZWdpb246c3RhdGUgaW4gdGhlIHBvcHVsYXRpb24gb2YgaW50ZXJlc3QgY29udGFpbmVkIGV2ZXJ5IHNpemUgY2F0ZWdvcnkgKGJlbG93KS4NCmBgYHtyIGZyYW1lX2RpbWVuc2lvbnNfNCwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2ZyYW1lLnJkYSIpDQoNCnNmcmFtZSAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgc3RhdGUsIHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBzcHJlYWQoc2l6ZV9jYXQsIG4pICU+JQ0KICBwcmludCgpDQpgYGANCg0KQmVsb3csIHRoZSBzYW1wbGluZyBmcmFtZSB3YXMgc2VsZWN0ZWQgZG93biB0byBjcmVhdGUgYSBwb3N0LXN0cmF0aWZpY2F0aW9uIHRhYmxlLiBTb21lIG9mIHRoZSB2YXJpYWJsZXMgd2VyZSByZW5hbWVkIHRvIG1hdGNoIHRoZSBuYW1pbmcgY29udmVudGlvbnMgdXNlZCBpbiB0aGUgb2JzZXJ2YXRpb25hbCBkYXRhIGFib3ZlLiBUaGVyZSB3ZXJlIDUzNiB0eXBlcyBvZiBsYWtlcyBpbiB0aGUgcG9wdWxhdGlvbiBvZiBpbnRlcmVzdCB3aXRoIHJlc3BlY3QgdG8gdGhlIHNhbXBsaW5nIGRlc2lnbi4gVGhlIGNvdW50cyBvZiB0aG9zZSBsYWtlIHR5cGVzIChuX2xha2VzKSBhbmQgdGhlaXIgcHJvcG9ydGlvbnMgcmVsYXRpdmUgdG8gdGhlIHRvdGFsIHBvcHVsYXRpb24gb2YgbGFrZXMgaW4gdGhlIHNhbXBsaW5nIGZyYW1lIChwcm9wX2NlbGwpIGFyZSBpbmRpY2F0ZWQgYmVsb3cuDQpgYGB7ciBmaWx0ZXJfZnJhbWUsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NmcmFtZS5yZGEiKQ0KDQpwZnJhbWUgPC0gc2ZyYW1lICU+JQ0KICBtdXRhdGUob2JzID0gMSkgJT4lDQogIGdyb3VwX2J5KFdTQTksIHN0YXRlLCBzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShuX2xha2VzID0gc3VtKG9icyksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShwcm9wX2NlbGwgPSBuX2xha2VzL3N1bShuX2xha2VzKSkgJT4lDQogIG11dGF0ZSh0eXBlID0gInBvcHVsYXRpb24iKSANCg0Kc2F2ZShwZnJhbWUsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcGZyYW1lLnJkYSIpDQoNCnByaW50KHBmcmFtZSkNCmBgYA0KDQojIyBTYW1wbGUgdnMuIHBvcHVsYXRpb24NCkJlbG93LCB0aGUgbGFrZSBkaXN0cmlidXRpb25zIGluIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0IHdlcmUgY29tcGFyZWQgdG8gdGhlIHByb3BvcnRpb25zIGluIHRoZSBvYnNlcnZlZCBzYW1wbGUuIFRoZXJlIHdlcmUgMzUyIGxha2UgdHlwZXMgaW4gdGhlIHNhbXBsZSBjb21wYXJlZCB0byB0aGUgNTM2IGluIHRoZSBwb3B1bGF0aW9uIG9mIG9mIGludGVyZXN0LiBJbiB0b3RhbCwgdGhlcmUgd2VyZSA5ODQgb2JzZXJ2YXRpb25zIGRpc3RyaWJ1dGVkIGFjcm9zcyB0aGVzZSAzNTIgbGFrZSB0eXBlcyBpbiB0aGUgc2FtcGxlOyBhbmQgdGhlIG51bWJlciBvZiBzYW1wbGVzIHdhcyBub3QgZGlzdHJpYnV0ZWQgZXZlbmx5IGFjcm9zcyB0aGUgdHlwZXMuIFNvbWUgY2VsbHMgd2VyZSByZXByZXNlbnRlZCBieSBhcyBmZXcgYXMgMSBsYWtlLiBJbiB0b3RhbCwgNTM2LTM1MiA9IDE4NCBsYWtlIHR5cGVzIGluIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0IHdlcmUgbm90IHJlcHJlc2VudGVkIGluIHRoZSBzYW1wbGUuDQpgYGB7ciBzYW1wbGVfY2VsbF9jb3VudHMsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCnNhbXBfcHJvcHMgPC0gZGZfbW9kZWwgJT4lDQogIG11dGF0ZShvYnMgPSAxKSAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgc3RhdGUsIHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXplKG5fbGFrZXMgPSBzdW0ob2JzKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHByb3BfY2VsbCA9IHJvdW5kKG5fbGFrZXMgLyBzdW0obl9sYWtlcyksIDcpKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAic2FtcGxlIikgDQoNCnNhdmUoc2FtcF9wcm9wcywgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYW1wX3Byb3BzLnJkYSIpDQoNCnByaW50KHNhbXBfcHJvcHMpDQpgYGANCg0KQmVsb3csIGEgZ3JhcGhpY2FsIGNvbXBhcmlzb24gd2FzIGNvbnN0cnVjdGVkIHRvIGRlcGljdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGNlbGxzIGluIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0IF92ZXJzdXNfIHRob3NlIGluIHRoZSBzYW1wbGUuDQpgYGB7ciBjb21wYXJlX3NhbXBsZV9wb3BfY2VsbHMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTB9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWUucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHMucmRhIikNCg0KcGZyYW1lICU+JQ0KICBiaW5kX3Jvd3Moc2FtcF9wcm9wcykgJT4lDQogIGdncGxvdChhZXMoeCA9IGludGVyYWN0aW9uKFdTQTksIHN0YXRlLCBzaXplX2NhdCksIHkgPSBwcm9wX2NlbGwsIGdyb3VwID0gdHlwZSwgbGluZXR5cGUgPSB0eXBlKSkgKw0KICBnZW9tX3BvaW50KHN0YXQgPSAiaWRlbnRpdHkiLCBhZXMoIHNoYXBlID0gdHlwZSwgY29sb3IgPSB0eXBlKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgeGxhYigiV1NBOTpzdGF0ZTpzaXplIikgKw0KICB5bGFiKCJwcm9wb3J0aW9uIGluIGNlbGwiKQ0KYGBgDQoNCkFub3RoZXIgY29tcGFyaXNvbiBiZXR3ZWVuIHBvcHVsYXRpb24gYW5kIHNhbXBsZSB3YXMgY29uc3RydWN0ZWQgYmVsb3cgYnkgZWNvcmVnaW9uLiBUaGUgc2FtcGxlcyB3ZXJlIG5vdCBiYWxhbmNlZCBhY3Jvc3MgZWNvcmVnaW9ucy4gTGFrZXMgaW4gdGhlIENvYXN0YWwgUGxhaW5zIChDUEwpIGVjb3JlZ2lvbiwgZm9yIGV4YW1wbGUsIHdlcmUgY2xlYXJseSB1bmRlcnNhbXBsZWQgcmVsYXRpdmUgdG8gdGhlaXIgcHJvcG9ydGlvbiBvZiB0aGUgcG9wdWxhdGlvbi4NCmBgYHtyIGVjb19wcm9wc19wb3AsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3BmcmFtZS5yZGEiKQ0KDQpwZnJhbWVfZWNvIDwtIHBmcmFtZSAlPiUNCiAgZ3JvdXBfYnkoV1NBOSkgJT4lDQogIHN1bW1hcmlzZShuX2xha2VzID0gc3VtKG5fbGFrZXMpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUocHJvcF9jZWxsID0gcm91bmQobl9sYWtlcy9zdW0obl9sYWtlcyksIDcpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUodHlwZSA9ICdwb3B1bGF0aW9uJykgDQoNCnNhdmUocGZyYW1lX2VjbywgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWVfZWNvLnJkYSIpDQpgYGANCg0KYGBge3IgZWNvX3Byb3BzX3NhbXBsZSwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFLCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2FtcF9wcm9wcy5yZGEiKQ0KDQpzYW1wX3Byb3BzX2VjbyA8LSBzYW1wX3Byb3BzICU+JQ0KICBncm91cF9ieShXU0E5KSAlPiUNCiAgc3VtbWFyaXNlKG5fbGFrZXMgPSBzdW0obl9sYWtlcykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShwcm9wX2NlbGwgPSByb3VuZChuX2xha2VzL3N1bShuX2xha2VzKSwgNykpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSh0eXBlID0gJ3NhbXBsZScpDQoNCnNhdmUoc2FtcF9wcm9wc19lY28sIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2FtcF9wcm9wc19lY28ucmRhIikNCmBgYA0KDQpgYGB7ciBjb21wYXJlX2Vjb19zYW1wbGVfcG9wX2NlbGxzLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTZ9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWVfZWNvLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYW1wX3Byb3BzX2Vjby5yZGEiKQ0KDQpwZnJhbWVfZWNvICU+JQ0KICBiaW5kX3Jvd3Moc2FtcF9wcm9wc19lY28pICU+JQ0KICBnZ3Bsb3QobWFwcGluZyA9IGFlcyh4ID0gV1NBOSwgeSA9IHByb3BfY2VsbCwgZ3JvdXAgPSB0eXBlLCBsaW5ldHlwZSA9IHR5cGUpKSArDQogIGdlb21fcG9pbnQoc3RhdCA9ICJpZGVudGl0eSIsIGFlcyggc2hhcGUgPSB0eXBlLCBjb2xvciA9IHR5cGUpLCBzaXplID0gMykgKw0KICBnZW9tX2xpbmUoKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYigiRWNvcmVnaW9uIikgKw0KICB5bGFiKCJwcm9wb3J0aW9uIGluIGNlbGwiKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkNCmBgYA0KDQpBIHNpbWlsYXIgY29tcGFyaXNvbiBieSBzdGF0ZSB3YXMgY29uc3RydWN0ZWQgYmVsb3cuDQpgYGB7ciBzdGF0ZV9wcm9wc19wb3AsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3BmcmFtZS5yZGEiKQ0KDQpwZnJhbWVfc3RhdGUgPC0gcGZyYW1lICU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZShuX2xha2VzID0gc3VtKG5fbGFrZXMpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUocHJvcF9jZWxsID0gcm91bmQobl9sYWtlcy9zdW0obl9sYWtlcyksIDcpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUodHlwZSA9ICdwb3B1bGF0aW9uJykNCg0Kc2F2ZShwZnJhbWVfc3RhdGUsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcGZyYW1lX3N0YXRlLnJkYSIpDQpgYGANCg0KYGBge3Igc3RhdGVfcHJvcHNfc2FtcGxlLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYW1wX3Byb3BzLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYW1wX3Byb3BzLnJkYSIpDQoNCnNhbXBfcHJvcHNfc3RhdGUgPC0gc2FtcF9wcm9wcyAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2Uobl9sYWtlcyA9IHN1bShuX2xha2VzKSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHByb3BfY2VsbCA9IHJvdW5kKG5fbGFrZXMvc3VtKG5fbGFrZXMpLCA3KSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAnc2FtcGxlJykNCg0Kc2F2ZShzYW1wX3Byb3BzX3N0YXRlLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHNfc3RhdGUucmRhIikNCmBgYA0KDQpgYGB7ciBjb21wYXJlX3N0YXRlX3NhbXBsZV9wb3BfY2VsbHMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTB9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWVfc3RhdGUucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHNfc3RhdGUucmRhIikNCg0KcGZyYW1lX3N0YXRlICU+JQ0KICBiaW5kX3Jvd3Moc2FtcF9wcm9wc19zdGF0ZSkgJT4lDQogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSBzdGF0ZSwgeSA9IHByb3BfY2VsbCwgZ3JvdXAgPSB0eXBlLCBsaW5ldHlwZSA9IHR5cGUpKSArDQogIGdlb21fcG9pbnQoc3RhdCA9ICJpZGVudGl0eSIsIGFlcyhzaGFwZSA9IHR5cGUsIGNvbG9yID0gdHlwZSkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKSArDQogIHhsYWIoIlN0YXRlIikgKw0KICB5bGFiKCJwcm9wb3J0aW9uIGluIGNlbGwiKQ0KYGBgDQoNCkZpbmFsbHksIGEgY29tcGFyaXNvbiBieSBsYWtlIHNpemUgY2F0ZWdvcnkgaXMgc2hvd24gYmVsb3cuIE5vdGUgdGhhdCBzbWFsbCBsYWtlcyB3ZXJlIHVuZGVyLXNhbXBsZWQgcmVsYXRpdmUgdG8gbGFyZ2VyIGxha2VzIGJ5IGRlc2lnbi4NCmBgYHtyIHNpemVfcHJvcHNfcG9wLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWUucmRhIikNCg0KcGZyYW1lX3NpemUgPC0gcGZyYW1lICU+JQ0KICBncm91cF9ieShzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShuX2xha2VzID0gc3VtKG5fbGFrZXMpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUocHJvcF9jZWxsID0gcm91bmQobl9sYWtlcy9zdW0obl9sYWtlcyksIDcpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUodHlwZSA9ICdwb3B1bGF0aW9uJykNCg0Kc2F2ZShwZnJhbWVfc2l6ZSwgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wZnJhbWVfc2l6ZS5yZGEiKQ0KYGBgDQoNCmBgYHtyIHNpemVfcHJvcHNfc2FtcGxlLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYW1wX3Byb3BzLnJkYSIpDQoNCnNhbXBfcHJvcHNfc2l6ZSA8LSBzYW1wX3Byb3BzICU+JQ0KICBncm91cF9ieShzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShuX2xha2VzID0gc3VtKG5fbGFrZXMpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUocHJvcF9jZWxsID0gcm91bmQobl9sYWtlcy9zdW0obl9sYWtlcyksIDcpKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUodHlwZSA9ICdzYW1wbGUnKQ0KDQpzYXZlKHNhbXBfcHJvcHNfc2l6ZSwgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9zYW1wX3Byb3BzX3NpemUucmRhIikNCmBgYA0KDQpgYGB7ciBjb21wYXJlX3NpemVfc2FtcGxlX3BvcF9jZWxscywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcGZyYW1lX3NpemUucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhbXBfcHJvcHNfc2l6ZS5yZGEiKQ0KDQpwZnJhbWVfc2l6ZSAlPiUNCiAgYmluZF9yb3dzKHNhbXBfcHJvcHNfc2l6ZSkgJT4lDQogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSBzaXplX2NhdCwgeSA9IHByb3BfY2VsbCwgZ3JvdXAgPSB0eXBlLCBsaW5ldHlwZSA9IHR5cGUpKSArDQogIGdlb21fcG9pbnQoc3RhdCA9ICJpZGVudGl0eSIsIGFlcyggc2hhcGUgPSB0eXBlLCBjb2xvciA9IHR5cGUpKSArDQogIGdlb21fbGluZSgpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKCJTaXplIGNhdGVnb3J5IikgKw0KICB5bGFiKCJwcm9wb3J0aW9uIGluIGNlbGwiKQ0KYGBgDQoNCiMjIFNhbXBsZS1iYXNlZCBlc3RpbWF0ZXMNClRoZSBvdmVyYWxsIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBmb3IgTjJPIGluIHRoZSBzYW1wbGU6DQpgYGB7ciBzYW1wbGVfc3VtbWFyeV9uMm99DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG4ybyksDQogICAgICAgICAgICAgc2QgPSBzZChuMm8pKSAlPiUNCiAgcHJpbnQoKQ0KYGBgDQoNClRoZSBzYW1lIHN1bW1hcnkgZm9yIGVxdWlsaWJyaXVtIE4yTzoNCmBgYHtyIHNhbXBsZV9zdW1tYXJ5X24yb2VxfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KZGZfbW9kZWwgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm9fZXEpLA0KICAgICAgICAgICAgIHNkID0gc2QobjJvX2VxKSkgJT4lDQogIHByaW50KCkNCmBgYA0KDQpUaGUgc2F0dXJhdGlvbiByYXRpbyAoaS5lLiwgTjJPIC8gTjJPLWVxKToNCmBgYHtyIHNhbXBsZV9zdW1tYXJ5X24yb3NhdH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmRmX21vZGVsICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4objJvIC8gbjJvX2VxKSwNCiAgICAgICAgICAgICBzZCA9IHNkKG4ybyAvIG4yb19lcSkpICU+JQ0KICBwcmludCgpDQpgYGANCg0KRmluYWxseSwgcm91Z2hseSA2NyUgb2YgbGFrZXMgaW4gdGhlIHNhbXBsZSB3ZXJlIHVuZGVyc2F0dXJhdGVkIChpLmUuLCBzYXR1cmF0aW9uIHJhdGlvIDwgMSk6DQpgYGB7ciBzYW1wbGVfc3VtbWFyeV9wcm9wc2F0fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KZGZfbW9kZWwgJT4lDQogIHN1bW1hcmlzZShwcm9wX3VuZGVyc2F0ID0gc3VtKChuMm8gLyBuMm9fZXEpIDwgMSkgLyA5ODQpICU+JQ0KICBwcmludCgpDQpgYGANCg0KVXNpbmcgb25seSB0aGUgc2FtcGxlIG9ic2VydmF0aW9ucywgYSBwbG90IHdhcyBjb25zdHJ1Y3RlZCBiZWxvdyBvZiB0aGUgb3ZlcmFsbCBtZWFuIChkYXNoZWQgbGluZSkgYWxvbmcgd2l0aCB0aGUgZWNvcmVnaW9uLXNwZWNpZmljIG1lYW5zIChibGFjayBjaXJjbGVzKS4gVGhlIHNoYWRlZCBhcmVhcyBpbmRpY2F0ZSArLy0gMSBzdGFuZGFyZCBkZXZpYXRpb24uIE5laXRoZXIgZGlzc29sdmVkIE4yTyBub3IgdGhlIHNhdHVyYXRpb24gcmF0aW8gd2VyZSBjbGVhcmx5IHN0cnVjdHVyZWQgYnkgZWNvcmVnaW9uIGluIHRoZSBzYW1wbGUsIGJ1dCB0aGVyZSBkaWQgYXBwZWFyIHRvIGJlIHNvbWUgc3RydWN0dXJlIGluIHRoZSBlcXVpbGlicml1bSBOMk8gb2JzZXJ2YXRpb25zLg0KYGBge3Igc2FtcGxlX3N1bW1hcnlfZWNvLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpwMSA8LSBkZl9tb2RlbCAlPiUNCiAgZ3JvdXBfYnkoV1NBOSkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm8pLA0KICAgICAgICAgICAgIHNkID0gc2QoIG4ybykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBXU0E5LCB5ID0gbWVhbiwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IG1lYW4gLSBzZCwgeW1heCA9IG1lYW4gKyBzZCwgeCA9IFdTQTkpLCBmaWxsID0gJ2xpZ2h0Z3JleScsIGFscGhhID0gLjcpKw0KICBnZW9tX2xpbmUoYWVzKHggPSBXU0E5LCB5ID0gbWVhbikpKw0KICBnZW9tX3BvaW50KCkrDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDguNzIsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKyANCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkgKyANCiAgeWxhYigiIikgKw0KICBnZ3RpdGxlKCJOMk8iKQ0KDQpwMiA8LSBkZl9tb2RlbCAlPiUNCiAgZ3JvdXBfYnkoV1NBOSkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm9fZXEpLA0KICAgICAgICAgICAgIHNkID0gc2QobjJvX2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IFdTQTksIHkgPSBtZWFuLCBncm91cCA9IDEpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbWVhbiAtIHNkLCB5bWF4ID0gbWVhbiArIHNkLCB4ID0gV1NBOSksIGZpbGwgPSAnbGlnaHRncmV5JywgYWxwaGEgPSAuNykrDQogIGdlb21fbGluZShhZXMoeCA9IFdTQTksIHkgPSBtZWFuKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNy40OCwgbGluZXR5cGUgPSAnZGFzaGVkJykgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArIA0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHlsYWIoIlNhbXBsZSBtZWFuIikgKw0KICBnZ3RpdGxlKCJOMk8gZXF1aWxpYnJpdW0iKQ0KDQpwMyA8LSBkZl9tb2RlbCAlPiUNCiAgZ3JvdXBfYnkoV1NBOSkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm8gLyBuMm9fZXEpLA0KICAgICAgICAgICAgIHNkID0gc2QobjJvIC8gbjJvX2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IFdTQTksIHkgPSBtZWFuLCBncm91cCA9IDEpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbWVhbiAtIHNkLCB5bWF4ID0gbWVhbiArIHNkLCB4ID0gV1NBOSksIGZpbGwgPSAnbGlnaHRncmV5JywgYWxwaGEgPSAuNykrDQogIGdlb21fbGluZShhZXMoeCA9IFdTQTksIHkgPSBtZWFuKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMS4xNywgbGluZXR5cGUgPSAnZGFzaGVkJykgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArICANCiAgeGxhYigiRWNvcmVnaW9uIikgKw0KICB5bGFiKCIiKSArDQogIGdndGl0bGUoIk4yTyBzYXR1cmF0aW9uIHJhdGlvIikNCg0KZ3JpZC5hcnJhbmdlKHAxLCBwMiwgcDMpDQpgYGANCg0KVGhlIHNhbWUgc3VtbWFyeSBieSBzdGF0ZSBpcyBiZWxvdy4NCmBgYHtyIHNhbXBsZV9zdW1tYXJ5X3N0YXRlLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpwMSA8LSBkZl9tb2RlbCAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4objJvKSwNCiAgICAgICAgICAgICBzZCA9IHNkKCBuMm8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3RhdGUsIHkgPSBtZWFuLCBncm91cCA9IDEpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbWVhbiAtIHNkLCB5bWF4ID0gbWVhbiArIHNkLCB4ID0gc3RhdGUpLCANCiAgICAgICAgICAgICAgZmlsbCA9ICdsaWdodGdyZXknLCANCiAgICAgICAgICAgICAgYWxwaGEgPSAuNykgKw0KICBnZW9tX2xpbmUoYWVzKHggPSBzdGF0ZSwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4LjcyLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArIA0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArIA0KICB5bGFiKCIiKSArDQogIGdndGl0bGUoIk4yTyIpDQoNCnAyIDwtIGRmX21vZGVsICU+JQ0KICBncm91cF9ieShzdGF0ZSkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm9fZXEpLA0KICAgICAgICAgICAgIHNkID0gc2QobjJvX2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHN0YXRlLCB5ID0gbWVhbiwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IG1lYW4gLSBzZCwgeW1heCA9IG1lYW4gKyBzZCwgeCA9IHN0YXRlKSwgDQogICAgICAgICAgICAgIGZpbGwgPSAnbGlnaHRncmV5JywgDQogICAgICAgICAgICAgIGFscGhhID0gLjcpICsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gc3RhdGUsIHkgPSBtZWFuKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNy40OCwgbGluZXR5cGUgPSAnZGFzaGVkJykgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArIA0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIHlsYWIoIlNhbXBsZSBtZWFuIikgKw0KICBnZ3RpdGxlKCJOMk8gZXF1aWxpYnJpdW0iKQ0KDQpwMyA8LSBkZl9tb2RlbCAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4objJvIC8gbjJvX2VxKSwNCiAgICAgICAgICAgICBzZCA9IHNkKG4ybyAvIG4yb19lcSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzdGF0ZSwgeSA9IG1lYW4sIGdyb3VwID0gMSkpICsNCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuIC0gc2QsIHltYXggPSBtZWFuICsgc2QsIHggPSBzdGF0ZSksIA0KICAgICAgICAgICAgICBmaWxsID0gJ2xpZ2h0Z3JleScsIA0KICAgICAgICAgICAgICBhbHBoYSA9IC43KSsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gc3RhdGUsIHkgPSBtZWFuKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMS4xNywgbGluZXR5cGUgPSAnZGFzaGVkJykgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkgKyANCiAgeGxhYigiU3RhdGUiKSArDQogIHlsYWIoIiIpICsNCiAgZ2d0aXRsZSgiTjJPIHNhdHVyYXRpb24gcmF0aW8iKQ0KDQpncmlkLmFycmFuZ2UocDEsIHAyLCBwMykNCmBgYA0KDQpGaW5hbGx5LCB0aGUgc2FtZSBzdW1tYXJ5IGJ5IHNpemUgY2F0ZWdvcnk6DQpgYGB7ciBzYW1wbGVfc3VtbWFyeV9zaXplLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpwMSA8LSBkZl9tb2RlbCAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQpICU+JQ0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4objJvKSwNCiAgICAgICAgICAgICBzZCA9IHNkKCBuMm8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2l6ZV9jYXQsIHkgPSBtZWFuLCBncm91cCA9IDEpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbWVhbiAtIHNkLCB5bWF4ID0gbWVhbiArIHNkLCB4ID0gc2l6ZV9jYXQpLCBmaWxsID0gJ2xpZ2h0Z3JleScsIGFscGhhID0gLjcpKw0KICBnZW9tX2xpbmUoYWVzKHggPSBzaXplX2NhdCwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA4LjcyLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogIHRoZW1lX3RpZHliYXllcygpICsgDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsgDQogIHlsYWIoIiIpICsNCiAgZ2d0aXRsZSgiTjJPIikNCg0KcDIgPC0gZGZfbW9kZWwgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG4yb19lcSksDQogICAgICAgICAgICAgc2QgPSBzZChuMm9fZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2l6ZV9jYXQsIHkgPSBtZWFuLCBncm91cCA9IDEpKSArDQogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbWVhbiAtIHNkLCB5bWF4ID0gbWVhbiArIHNkLCB4ID0gc2l6ZV9jYXQpLCBmaWxsID0gJ2xpZ2h0Z3JleScsIGFscGhhID0gLjcpKw0KICBnZW9tX2xpbmUoYWVzKHggPSBzaXplX2NhdCwgeSA9IG1lYW4pKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA3LjQ4LCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogIHRoZW1lX3RpZHliYXllcygpICsgDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgeWxhYigiU2FtcGxlIG1lYW4iKSArDQogIGdndGl0bGUoIk4yTyBlcXVpbGlicml1bSIpDQoNCnAzIDwtIGRmX21vZGVsICU+JQ0KICBncm91cF9ieShzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihuMm8gLyBuMm9fZXEpLA0KICAgICAgICAgICAgIHNkID0gc2QobjJvIC8gbjJvX2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNpemVfY2F0LCB5ID0gbWVhbiwgZ3JvdXAgPSAxKSkgKw0KICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IG1lYW4gLSBzZCwgeW1heCA9IG1lYW4gKyBzZCwgeCA9IHNpemVfY2F0KSwgZmlsbCA9ICdsaWdodGdyZXknLCBhbHBoYSA9IC43KSsNCiAgZ2VvbV9saW5lKGFlcyh4ID0gc2l6ZV9jYXQsIHkgPSBtZWFuKSkrDQogIGdlb21fcG9pbnQoKSsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMS4xNywgbGluZXR5cGUgPSAnZGFzaGVkJykgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkgKyANCiAgeGxhYigiU2l6ZSBjbGFzcyIpICsNCiAgeWxhYigiIikgKw0KICBnZ3RpdGxlKCJOMk8gc2F0dXJhdGlvbiByYXRpbyIpDQoNCmdyaWQuYXJyYW5nZShwMSwgcDIsIHAzKQ0KYGBgDQoNCiMjIFNhbXBsZSBkYXRhIGV4cGxvcmF0aW9uDQpCZWxvdywgdGhlIGVtcGlyaWNhbCBkaXN0cmlidXRpb24gb2YgTjJPIG9ic2VydmF0aW9ucyBpbiB0aGUgc2FtcGxlIHdhcyBzdW1tYXJpemVkIHVzaW5nIGEgZGVuc2l0eSBhbmQgcnVnIHBsb3QgYmVsb3cuIE5vdGUgdGhlIG5hdHVyYWwgbG9nIHNjYWxlIG9mIHRoZSB4IGF4aXMuIEJvdGggdGhlIE4yTyBhbmQgZXF1aWxpYnJpdW0gTjJPIGRhdGEgaGFkIGNvbnNpZGVyYWJsZSByaWdodCBza2V3IGV2ZW4gYWZ0ZXIgdGhlIGxvZyB0cmFuc2Zvcm1hdGlvbiwgd2hpY2ggd2FzIG5vdCB1bmV4cGVjdGVkIGFuZCBoYXMgYmVlbiBub3RlZCBpbiBvdGhlciBzdHVkaWVzIFtAV2ViYl9ldGFsXzIwMTldLiBUaGUgc2F0dXJhdGlvbiByYXRpbyB3YXMgYWxzbyBza2V3ZWQgc2luY2UgaXQgd2FzIGRlcml2ZWQgZnJvbSB0aGUgb3RoZXIgdHdvIG9ic2VydmVkIHZhcmlhYmxlcyAoaS5lLiwgc2F0X3JhdGlvID0gbjJvIC8gbjJvX2VxKS4NCmBgYHtyIHN1bW1hcnlfTjJPLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTUsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpwMSA8LSBkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbjJvKSkgKw0KICBnZW9tX2JveHBsb3QoYWVzKHggPSBuMm8sIHkgPSAtMC41KSwgb3V0bGllci5zaGFwZSA9IE5BLCBhbHBoYSA9IDAuNykgKyANCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gbjJvKSkgKw0KICBnZW9tX3J1ZyhhZXMoeCA9IG4ybyksIHNob3cubGVnZW5kID0gRiApICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIiwgYnJlYWtzID0gYygwLCA1LCAxMCwgMjUsIDUwLCAxNTApKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHhsYWIoIk4yTyAobm1vbC9MKSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KcDIgPC0gZGZfbW9kZWwgJT4lDQogIGdncGxvdChhZXMoeCA9IG4yb19lcSkpICsNCiAgZ2VvbV9ib3hwbG90KGFlcyh4ID0gbjJvX2VxLCB5ID0gLTAuNSksIG91dGxpZXIuc2hhcGUgPSBOQSwgYWxwaGEgPSAwLjcpICsgDQogIGdlb21fZGVuc2l0eShhZXMoeCA9IG4yb19lcSkpICsNCiAgZ2VvbV9ydWcoYWVzKHggPSBuMm9fZXEpLCBzaG93LmxlZ2VuZCA9IEYgKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgeGxhYigiRXF1aWxpYnJpdW0gTjJPIChubW9sL0wpIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpKQ0KDQpwMyA8LSBkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbjJvIC8gbjJvX2VxKSkgKw0KICBnZW9tX2JveHBsb3QoYWVzKHggPSBuMm8gLyBuMm9fZXEsIHkgPSAtMC41KSwgb3V0bGllci5zaGFwZSA9IE5BLCBhbHBoYSA9IDAuNykgKyANCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gbjJvIC8gbjJvX2VxKSkgKw0KICBnZW9tX3J1ZyhhZXMoeCA9IG4ybyAvIG4yb19lcSksIHNob3cubGVnZW5kID0gRiApICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIiwgYnJlYWtzID0gYygwLCAxLCA1LCAxMCwgMjApKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHhsYWIoIk4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpKQ0KDQpncmlkLmFycmFuZ2UocDEsIHAyLCBwMykNCmBgYA0KDQpCZWxvdyBhcmUgcGxvdHMgb2YgTjJPIHZzLiBOTzMuIFRoZSBmaXJzdCBwbG90IHNob3dzIGxvZyhOMk8pIHZzLiBsb2coTk8zKSwgYXMgd2VsbCBhcyB0aGUgb3JkaW5hbCBjYXRlZ29yaWVzIGFzc2lnbmVkIHRvIE5PMyAodmVydGljYWwgbGluZXMpLiBUaGUgbGVmdG1vc3QgdmVydGljYWwgbGluZSBpcyBkYXNoZWQgYW5kIHNlcGFyYXRlcyB0aGUgTk8zIG9ic2VydmF0aW9ucyBiZWxvdyB0aGUgZGV0ZWN0aW9uIGxpbWl0Lg0KYGBge3Igc3VtbWFyeV9OMk9fdnNfTk8zLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTYsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG5vMyksIHkgPSBsb2cobjJvKSkpICsNCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEYpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc3BhbiA9IDIpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gLTcuNSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAtNS41KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IC0zLjUpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gLTEuNSkgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQpJbiB0aGUgcGxvdCBhYm92ZSwgdGhlIHRyZW5kIGlzIGluY3JlYXNpbmcgYW5kIG5vbmxpbmVhciBvbiB0aGUgbG9nIHNjYWxlLiBUaGUgaW5jcmVhc2luZyB2YXJpYW5jZSBpbiBOMk8gYWxvbmcgdGhlIE5PMyBncmFkZWllbnQgc3VnZ2VzdGVkIGEgcG90ZW50aWFsIG1lZGlhdG9yIG9mIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBOTzMgb24gTjJPLiBCZWxvdyBhcmUgcGxvdHMgb2YgTjJPIHZzLiBOTzMgZm9yIDYgcXVhbnRpbGVzIG9mIHRoZSBzdXJmYWNlIHRlbXBlcmF0dXJlIG1lYXN1cmVtZW50cyAocXVhbnRpbGVzIGluY3JlYXNpbmcgZnJvbSAxIHRvIDYpLiBUaGlzIHBsb3QgYmVsb3cgc3VnZ2VzdGVkIHRoYXQgdGhlIE5PMyBlZmZlY3Qgb24gTjJPIG1heSBoYXZlIGJlZW4gc3Ryb25nZXIgaW4gbGFrZXMgd2l0aCBoaWdoZXIgb2JzZXJ2ZWQgdGVtcGVyYXR1cmVzLg0KYGBge3Igc3VtbWFyeV9OMk9fdnNfTk8zX3N1cmZ0ZW1wLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG5vMyksIHkgPSBsb2cobjJvKSkpICsNCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEYpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc3BhbiA9IDIpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKw0KICBmYWNldF93cmFwKH4gYXMuZmFjdG9yKG50aWxlKHN1cmZ0ZW1wLCA2KSkpICsNCiAgdGhlbWVfYncoKQ0KYGBgDQoNClRoZSBuZXh0IHBsb3QgYmVsb3cgc2hvd3MgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIE4yTyBhbmQgTk8zIGF0IDYgZGlmZmVyZW50IHF1YW50aWxlcyAoaW5jcmVhc2luZyAxIHRvIDYpIG9mIHRoZSBsb2ctc2NhbGVkIGxha2Ugc3VyZmFjZSBhcmVhIGVzdGltYXRlcy4NCmBgYHtyIHN1bW1hcnlfTjJPX3ZzX05PM19sb2dhcmVhLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG5vMyksIHkgPSBsb2cobjJvKSkpICsNCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEYpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc3BhbiA9IDIpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKw0KICBmYWNldF93cmFwKH4gYXMuZmFjdG9yKG50aWxlKGxvZ19hcmVhLCA2KSkpICsNCiAgdGhlbWVfYncoKQ0KYGBgDQoNClNpbWlsYXIgcGxvdHMgYXJlIGJlbG93LCBidXQgd2l0aCBOTzMgZXhwcmVzc2VkIGFzIGFuIG9yZGVyZWQgY2F0ZWdvcmljYWwgdmFyaWFibGUgd2l0aCA1IGxldmVscy4gVGhlIHBvc2l0aXZlIGFuZCBtb25vdG9uaWMgdHJlbmRzIGFyZWEgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgcGxvdHMgd2hlcmUgTk8zIHdhcyB0cmVhdGVkIGFzIGNvbnRpbnVvdXMuIE5vdGUgdGhlIGxhcmdlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgaW4gdGhlIGZpcnN0IE5PMyBjYXRlZ29yeSAobm8zX2NhdCA9IDEpLiBUaGlzIGNhdGVnb3J5IHJlcHJlc2VudGVkIGFsbCBvZiB0aGUgY2Vuc29yZWQgb2JzZXJ2YXRpb25zIGZvciBOTzMsIHdoaWNoIHdhcyBtb3N0IG9mIHRoZSBkYXRhLg0KYGBge3Igc3VtbWFyeV9OMk9fdnNfTk8zY2F0LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTYsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbm8zX2NhdCwgeSA9IGxvZyhuMm8pLCBjb2xvciA9IDEpKSArDQogIGdlb21fcG9pbnQoIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2UoKSwgc2hvdy5sZWdlbmQgPSBGICkgKw0KICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BLCBub3RjaCA9IFRSVUUsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjcpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KYGBge3Igc3VtbWFyeV9OMk9fdnNfTk8zY2F0X3N1cmZ0ZW1wLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpkZl9tb2RlbCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbm8zX2NhdCwgeSA9IGxvZyhuMm8pLCBjb2xvciA9IDEpKSArDQogIGdlb21fcG9pbnQoIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2UoKSwgc2hvdy5sZWdlbmQgPSBGICkgKw0KICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC43KSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsNCiAgZmFjZXRfd3JhcCh+IGFzLmZhY3RvcihudGlsZShzdXJmdGVtcCwgNikpKSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQpgYGB7ciBzdW1tYXJ5X04yT192c19OTzNjYXRfbG9nYXJlYSwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KZGZfbW9kZWwgJT4lDQogIGdncGxvdChhZXMoeCA9IG5vM19jYXQsIHkgPSBsb2cobjJvKSwgY29sb3IgPSAxKSkgKw0KICBnZW9tX3BvaW50KCBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKCksIHNob3cubGVnZW5kID0gRiApICsNCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNykgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIGZhY2V0X3dyYXAofiBhcy5mYWN0b3IobnRpbGUobG9nX2FyZWEsIDYpKSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KQmVsb3cgaXMgYSBwbG90IG9mIGxvZyhOMk8pIHZzLiBsb2coTk8zKSBieSBlY29yZWdpb24sIHdoaWNoIHN1Z2dlc3RlZCB0aGF0IHRoZSBOTzMgZWZmZWN0IG9uIE4yTyBtYXkgaGF2ZSB2YXJpZWQgYnkgZWNvcmVnaW9uLg0KYGBge3Igc3VtbWFyeV9OMk9fdnNfTk8zX2Vjb3JlZ2lvbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KZGZfbW9kZWwgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvZyhubzMpLCB5ID0gbG9nKG4ybykpKSArDQogIGdlb21fcG9pbnQoc2hvdy5sZWdlbmQgPSBGKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNwYW4gPSAyKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IC03LjUsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gLTUuNSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAtMy41KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IC0xLjUpICsNCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKw0KICBmYWNldF93cmFwKH4gV1NBOSkgKw0KICB0aGVtZV9idygpDQpgYGANCg0KQmVsb3cgaXMgdGhlIHNhbWUgcGxvdCBhcyBhYm92ZSBidXQgZm9yIHRoZSBvcmRlcmVkIGNhdGVnb3JpY2FsIHZlcnNpb24gb2YgTk8zLg0KYGBge3Igc3VtbWFyeV9OMk9fdnNfTk8zY2F0X2Vjb3JlZ2lvbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KZGZfbW9kZWwgJT4lDQogIGdncGxvdChhZXMoeCA9IG5vM19jYXQsIHkgPSBsb2cobjJvKSwgY29sb3IgPSAxKSkgKw0KICBnZW9tX3BvaW50KCBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKCksIHNob3cubGVnZW5kID0gRiApICsNCiAgZ2VvbV9ib3hwbG90KGFlcyh4ID0gbm8zX2NhdCwgeSA9IGxvZyhuMm8pKSwgDQogICAgICAgICAgICAgICBvdXRsaWVyLnNoYXBlID0gTkEsIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCANCiAgICAgICAgICAgICAgIGFscGhhID0gMC43KSArIA0KICBmYWNldF93cmFwKH4gV1NBOSkgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQpBIHBsb3QgYmVsb3cgc2hvd3MgdHJlbmRzIGJ5IHN0YXRlIHdpdGhpbiBqdXN0IHRoZSBUZW1wZXJhdGUgUGxhaW5zIChUUEwpIGVjb3JlZ2lvbi4gV2l0aGluIHN0YXRlcywgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgd2VyZSByZWxhdGl2ZWx5IHNtYWxsLCBidXQgdGhlIHRyZW5kcyBhcHBlYXJlZCBjbG9zZXIgdG8gbGluZWFyLg0KYGBge3Igc3VtbWFyeV9OMk9fdnNfTk8zX3dzYTlzdGF0ZTMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmRmX21vZGVsICU+JQ0KICBmaWx0ZXIoV1NBOSA9PSAiVFBMIikgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvZyhubzMpLCB5ID0gbG9nKG4ybyksIGdyb3VwID0gc3RhdGUsIGNvbG9yID0gc3RhdGUpKSArDQogIGdlb21fcG9pbnQoc2hvdy5sZWdlbmQgPSBGKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNwYW4gPSAyLCBhbHBoYSA9IDAuMSkgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQojIE1vZGVsIGZpdHRpbmcNClRoZSBmaXJzdCByZWdyZXNzaW9uIG1vZGVsIHdhcyBjb25zdHJ1Y3RlZCB0byBlc3RpbWF0ZSB0aGUgam9pbnQgZGlzdHJpYnV0aW9uIG9mIGxvZy10cmFuc2Zvcm1lZCBOMk8gYW5kIGVxdWlsaWJyaXVtIE4yTyBjb25kaXRpb25hbCBvbiB0aGUgdGhlIGRlc2lnbiBmYWN0b3JzLiBFYWNoIGxvZy10cmFuc2Zvcm1lZCBvYnNlcnZhdGlvbiwgJGkgXGluIDEsLi4sTj05ODQkLCBmb3IgZWFjaCByZXNwb25zZSwgJHAgXGluIDE6UD0yJCwgd2FzIGFzc3VtZWQgdG8gYmUgZHJhd24gZnJvbSBhIG11bHRpdmFyaWF0ZSBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGggdGhlIHBhcmFtZXRlcnMgJFxudSQgYW5kICRcU2lnbWEkLCB3aGVyZSAkXG51JCBpcyB0aGUgbXVsdGl2YXJpYXRlIG1lYW4gZXN0aW1hdGVkIGNvbmRpdGlvbmFsIG9uIHRoZSBkZXNpZ24gZWZmZWN0cyBhbmQgJFxTaWdtYSQgaXMgYSBjb3ZhcmlhbmNlIG1hdHJpeCBjb250YWluaW5nIHRoZSBvYnNlcnZhdGlvbi1sZXZlbCB2YXJpYW5jZXMgYW5kIHJlc2lkdWFsIGNvcnJlbGF0aW9uOg0KJCRZIFxzaW0gTVZOKFxudSwgXFNpZ21hKSQkDQoNClRoZSBtdWx0aXZhcmlhdGUgbWVhbiBpcyBhIHZlY3RvciBvZiBtZWFuIHBhcmFtZXRlcnMsICRcbnU6W1xtdV97cD0xfSwgXG11X3twPTJ9XSQsIGZvciBlYWNoIHJlc3BvbnNlLiBFYWNoIG1lYW4gaXMgZnVydGhlciBkZWZpbmVkIGJ5IGEgbGluZWFyIGNvbWJpbmF0aW9uIG9mIHBhcmFtZXRlcnMgd2hlcmUsIGZvciBlYWNoIHJlc3BvbnNlICRwJCBhbmQgb2JzZXJ2YXRpb24gJGkkOg0KDQokJFxtdV97cGl9ID0gXGFscGhhX3swKHBpKX0gKyBcYWxwaGFfezEocGlqKX0gKyBcYWxwaGFfezIocGlqayl9ICsgXGFscGhhX3szKHBpamtsKX0gXFwNClxhbHBoYV8xIFxzaW0gTVZOKDAsIFxMYW1iZGFfMSkgXFwNClxhbHBoYV8yIFxzaW0gTVZOKDAsIFxMYW1iZGFfMikgXFwNClxhbHBoYV8zIFxzaW0gTVZOKDAsIFxMYW1iZGFfMykkJA0KDQpUaGUgbGluZWFyIGNvbWJpbmF0aW9uIG9mIHBhcmFtZXRlcnMgZGVmaW5pbmcgJFxtdSQgYWJvdmUgaW5jbHVkZSBhIGZpeGVkIGdsb2JhbCBpbnRlcmNlcHQsICRhXzAkLCB0aGF0IGlzIGVzdGltYXRlZCBkaXJlY3RseSBmcm9tIHRoZSBkYXRhLCBhbmQgdGhyZWUgc2VwYXJhdGUsIGxhdGVudCBncm91cC1sZXZlbCBlZmZlY3RzIG1hdHJpY2VzLCAkXGFscGhhXzEsIFxhbHBoYV8yLCBcYWxwaGFfMyQuIFRoZSBncm91cCBlZmZlY3RzIHdlcmUgYXNzdW1lZCB0byBiZSBtdWx0aXZhcmlhdGUgbm9ybWFsIGFuZCBhcmUgY2VudGVyZWQgb24gemVybyBpbiBtdWx0aXZhcmlhdGUgc3BhY2UuIFRoZSBzcHJlYWQgb2YgdGhlIGVmZmVjdHMgYXJvdW5kIHplcm8gYXJlIGRldGVybWluZWQgYnkgYSBjb3ZhcmlhbmNlIG1hdHJpeCwgJFxMYW1iZGFfMSwgXExhbWJkYV8yLCBcdGV4dHtvciB9IFxMYW1iZGFfMyQsIHdoaWNoIGFyZSBlc3RpbWF0ZWQgZGlyZWN0bHkgZnJvbSB0aGUgZGF0YS4gVGhlc2UgY292YXJpYW5jZSB0ZXJtcyBhcmUgZnVydGhlciBkZWZpbmVkIHdoZXJlOg0KDQokJFxMYW1iZGEgPSBcYmVnaW57cG1hdHJpeH0gMSAmIFx0YXVfe3A9MX0gXFwgXHRhdV97cD0yfSAmIDEgXGVuZHtwbWF0cml4fSBcY2hpIFxiZWdpbntwbWF0cml4fSAxICYgXHRhdV97cD0xfSBcXCBcdGF1X3twPTJ9ICYgMSBcZW5ke3BtYXRyaXh9JCQNCg0KVGhlICRcdGF1JCBwYXJhbWV0ZXJzIGFyZSB0aGUgZ3JvdXAtbGV2ZWwgc2NhbGUgcGFyYW1ldGVycywgd2hpY2ggY29uc3RyYWluIHRoZSBzcHJlYWQgb2YgZWZmZWN0cyBmb3IgZWFjaCByZXNwb25zZSwgYW5kICRcY2hpJCBjb21wcmlzZXMgdGhlIGdyb3VwLWxldmVsIHJlc2lkdWFsIGNvcnJlbGF0aW9uIG1hdHJpeDoNCg0KJCRcY2hpID0gXGJlZ2lue3BtYXRyaXh9IDEgJiBcdmFycmhvIFxcIFx2YXJyaG8gJiAxIFxlbmR7cG1hdHJpeH0kJA0KDQp3aGVyZWluICRcdmFycmhvJCBpcyB0aGUgZ3JvdXAtbGV2ZWwgcmVzaWR1YWwgY29ycmVsYXRpb24gYmV0d2VlbiByZXNwb25zZXMuDQoNClRoZSBleHBsaWNpdCBpbmRleGluZyBpbiB0aGUgbm90YXRpb24gYWJvdmUgY29udmV5cyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHBhcmFtZXRlcnMgYW5kIGVhY2ggb2JzZXJ2YXRpb24sICRpJCwgYW5kIGVtcGhhc2l6ZXMgdGhlIG5lc3RlZCBzdHJ1Y3R1cmUgb2YgdGhlIG9ic2VydmF0aW9ucyB3aXRoaW4gdGhlIGdyb3VwIGVmZmVjdHMuIFNwZWNpZmljYWxseSwgZXZlcnkgb2JzZXJ2YXRpb24sICRpJCwgd2FzIG5lc3RlZCBpbiBhIGxha2Ugc2l6ZSBjYXRlZ29yeSwgJGwkLCB3aGljaCB3YXMgbmVzdGVkIGluIGEgc3RhdGUsICRrJCwgYW5kIGVjb3JlZ2lvbiwgJGokLiBUaGUgcGFyYW1ldGVyICRcYWxwaGFfMSQsIHRoZXJlZm9yZSwgYWNjb3VudGVkIGZvciBlY29yZWdpb24tc2NhbGUgZ3JvdXAgZWZmZWN0cyBvciBkZXZpYXRpb25zIGZyb20gdGhlIGdsb2JhbCBtZWFuOyAkXGFscGhhXzIkIGFjY291bnRlZCBmb3Igc3RhdGUtbGV2ZWwgZ3JvdXAgZWZmZWN0cyBuZXN0ZWQgaW4gZWNvcmVnaW9uczsgYW5kICRcYWxwaGFfMyQgYWNjb3VudGVkIGZvciBsYWtlIHNpemUgZ3JvdXAgZWZmZWN0cyB3aXRoaW4gc3RhdGVzIGFuZCBlY29yZWdpb25zLiAgDQoNCkZpbmFsbHksIHRoZSBvYnNlcnZhdGlvbi1sZXZlbCBjb3ZhcmlhbmNlIHRlcm0sICRcU2lnbWEkLCB3YXMgcGFyYW1ldGVyaXplZCBhczoNCiQkXFNpZ21hID0gXGJlZ2lue3BtYXRyaXh9IDEgJiBcc2lnbWFfe3A9MX0gXFwgXHNpZ21hX3twPTJ9ICYgMSBcZW5ke3BtYXRyaXh9IFxPbWVnYSBcYmVnaW57cG1hdHJpeH0gMSAmIFxzaWdtYV97cD0xfSBcXCBcc2lnbWFfe3A9Mn0gJiAxIFxlbmR7cG1hdHJpeH0kJA0KDQp3aGVyZWluIHRoZSAkXHNpZ21hJCBwYXJhbWV0ZXJzIGFyZSB0aGUgb2JzZXJ2YXRpb24tbGV2ZWwgc3RhbmRhcmQgZGV2aWF0aW9ucyBmb3IgZWFjaCByZXNwb25zZSBhbmQgJFxPbWVnYSQgY29tcHJpc2VzIHRoZSBvYnNlcnZhdGlvbi1sZXZlbCByZXNpZHVhbCBjb3JyZWxhdGlvbiBtYXRyaXg6DQokJFxPbWVnYSA9IFxiZWdpbntwbWF0cml4fSAxICYgXHJobyBcXCBccmhvICYgMSBcZW5ke3BtYXRyaXh9JCQNCndoZXJlaW4gJFxyaG8kIGlzIHRoZSByZXNpZHVhbCBjb3JyZWxhdGlvbiBiZXR3ZWVuIHJlc3BvbnNlcy4NCg0KRm9yIG1vZGVsIGZpdHRpbmcsIHByaW9ycyB3ZXJlIG5lZWRlZCBmb3IgYWxsIHBhcmFtZXRlcnMgY29uZGl0aW9uZWQgZGlyZWN0bHkgb24gdGhlIGRhdGEsIHdoaWNoIGluY2x1ZGVkIHRoZSBnbG9iYWwgaW50ZXJjZXB0LCB0aGUgc2NhbGUgcGFyYW1ldGVycywgYW5kIHRoZSBjb3JyZWxhdGlvbiBtYXRyaWNlcy4gQSBub3JtYWwgb3IgR2F1c3NpYW4gcHJpb3IsICROKFxtdSA9IDIsIFxzaWdtYSA9IDEpJCBjZW50ZXJlZCBuZWFyIHRoZSAobG9nLXNjYWxlKSBkYXRhIG1lYW5zLCB3YXMgdXNlZCBmb3IgdGhlIGdsb2JhbCBpbnRlcmNlcHQgcGFyYW1ldGVyIGZvciBlYWNoIHJlc3BvbnNlLiBUaGlzIHByaW9yIHdhcyBjb25zaWRlcmVkIG1pbmltYWxseSBpbmZvcm1hdGl2ZSBhcyBpdCBwbGFjZWQgbW9zdCAofjgwJSkgb2YgdGhlIHByaW9yIG1hc3Mgb3ZlciB2YWx1ZXMgYmV0d2VlbiBhcHByb3hpbWF0ZWx5IDIgYW5kIDI3IG5nL0wgZm9yIG1lZGlhbiBOMk8gb3IgTjJPIGVxdWlsaWJyaXVtIGNvbmNlbnRyYXRpb24gYW5kIGluY2x1ZGVkIHN1cHBvcnQgaW4gdGhlIHRhaWxzIGZvciB2YWx1ZXMgYXBwcm9hY2hpbmcgMCBuZy9MIG9uIHRoZSBsb3dlciBlbmQgYW5kIDgwIG5nL0wgb24gdGhlIGhpZ2ggZW5kLiBXZSBwbGFjZWQgJEV4cCgyKSQgcHJpb3JzIG92ZXIgYWxsIHNjYWxlIHBhcmFtZXRlcnMsIHdoaWNoIHBsYWNlZCBtb3N0IG9mIHRoZSBzdXBwb3J0IGJldHdlZW4gdmFsdWVzIHZlcnkgY2xvc2UgdG8gMCBhbmQgdmFsdWVzIG5lYXIgMSAoY2VudHJhbCA4MCUgZGVuc2l0eSBpbnRlcnZhbCBmcm9tIGFwcHJveGltYXRlbHkgMC4wMDUgdG8gMS4xNSkuIEZpbmFsbHksIGZvciB0aGUgY29ycmVsYXRpb24gbWF0cmljZXMsIGFuICRMS0ooXGV0YSA9MikkIHByaW9yIHdhcyB1c2VkLCB3aGljaCwgZm9yIGEgMi1kaW1lbnNpb25hbCByZXNwb25zZSwgcGxhY2VkIG1vc3Qgc3VwcG9ydCBmb3IgY29ycmVsYXRpb25zIGJldHdlZW4gYXBwcm94aW1hdGVseSAtMC45IGFuZCAwLjkuIFRoaXMgcHJpb3Igc2VlbWVkIHJlYXNvbmFibGUgYXMgdGhlcmUgd2FzIG5vIGNsZWFyIGNhdXNhbCBtZWNoYW5pc21zIHRoYXQgd2VyZSB0aG91Z2h0IHRvIGVuc3VyZSBhIHN0cm9uZyBkaXJlY3QgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgTjJPIG1lYXN1cmVzLiBBbnkgcG90ZW50aWFsIHJlc2lkdWFsIGRlcGVuZGVuY2Ugd2FzIGV4cGVjdGVkIHRvIGJlIGluZGlyZWN0IGR1ZSB0bywgZm9yIGV4YW1wbGUsIGEgY29tbW9uIGNhdXNhbCBmYWN0b3IgKGUuZy4sIGVsZXZhdGlvbiwgdGVtcGVyYXR1cmUpLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBwcmlvciBjaG9pY2UgcmVjb21tZW5kYXRpb25zIGluIFN0YW4sIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL3N0YW4tZGV2L3N0YW4vd2lraS9Qcmlvci1DaG9pY2UtUmVjb21tZW5kYXRpb25zDQoNClRoZSAkXHRleHRiZnticm1zfSQgcGFja2FnZSBbQEJ1cmtuZXJfMjAxN10gZm9yICRcdGV4dGJme1J9JCBbQFJfQ29yZV9UZWFtXzIwMjFdIHdhcyB1c2VkIHRvIGZpdCBhbGwgb2YgdGhlIG1vZGVscyBpbiBhIGZ1bGx5IEJheWVzaWFuIHNldHRpbmcuIFRoZSBmb3JtdWxhIHN5bnRheCBvZiB0aGUgJFx0ZXh0YmZ7YnJtc30kIHBhY2thZ2UgaXMgc2ltaWxhciB0byB0aGUgc3ludGF4IHVzZWQgaW4gdGhlICRcdGV4dGJme2xtZTR9JCBwYWNrYWdlIHRoYXQgaXMgd2lkZWx5IHVzZWQgdG8gZml0IG1peGVkIGVmZmVjdHMgbW9kZWxzIGluIGZyZXF1ZW50aXN0IHNldHRpbmdzIEluIGVpdGhlciBwYWNrYWdlLCB0aGUgbGluZWFyIHByZWRpY3RvciBmb3IgJFxtdSQgZGVzY3JpYmVkIGFib3ZlIGNvdWxkIGJlIGV4cHJlc3NlZCBhczoNCg0KJCRcc2ltIDEgKyAoMXxXU0E5KSArICgxfFdTQTk6c3RhdGUpICsgKDF8V1NBOTpzdGF0ZTpzaXplKSQkDQoNCkluIHRoZSAkXHRleHRiZnticm1zfSQgcGFja2FnZSwgdGhlcmUgaXMgYWRkaXRpb25hbHkgZnVuY3Rpb25hbGl0eSBhbmQgc3ludGF4IGZvciBtdWx0aXZhcmlhdGUgcmVzcG9uc2VzIGFuZCBmb3IgYWxsb3dpbmcgdGhlIHZhcnlpbmcgaW50ZXJjZXB0cyBpbiBhIG11bHRpdmFyaWF0ZSBtb2RlbCB0byBiZSBjb3JyZWxhdGVkLCBlLmcuLDoNCg0KJCQgTl8yT197ZGlzc29sdmVkfVxzaW0gMSArICgxfGF8V1NBOSkgKyAoMXxifFdTQTk6c3RhdGUpICsgKDF8Y3xXU0E5OnN0YXRlOnNpemUpIFxcIA0KTl8yT197ZXF1aWxpYnJpdW19XHNpbSAxICsgKDF8YXxXU0E5KSArICgxfGJ8V1NBOTpzdGF0ZSkgKyAoMXxjfFdTQTk6c3RhdGU6c2l6ZSkkJA0KDQpUaGUgYWJvdmUgc3ludGF4IHdvdWxkIGluZGljYXRlIHRoYXQgdGhlIGxpbmVhciBwcmVkaWN0b3IgZm9yIGJvdGggcmVzcG9uc2VzIGluIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWwgaGF2ZSB0aGUgc2FtZSBncm91cC1sZXZlbCB2YXJ5aW5nIGVmZmVjdHMsIGFuZCB0aGF0IGVhY2ggb2YgdGhvc2UgZWZmZWN0cyBhcmUgYWxsb3dlZCB0byBiZSBjb3JyZWxhdGVkIGJldHdlZW4gcmVzcG9uc2VzLiANCg0KRm9yIHRoZSByZW1haW5kZXIgb2YgdGhpcyBkb2N1bWVudCwgb25seSB0aGlzIHNpbXBsaWZpZWQgc3ludGF4IGlzIHByZXNlbnRlZCB0byBkZXNjcmliZSB0aGUgbW9kZWwgcGFyYW1ldGVyaXphdGlvbnMuIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uICRcdGV4dGJme2JybXN9JCBmdW5jdGlvbmFsaXR5IGFuZCBzeW50YXggd2l0aCBtdWx0aXZhcmlhdGUgcmVzcG9uc2UgbW9kZWxzLCB0aGUgcGFja2FnZSB2aWduZXR0ZSBtYXkgYmUgaGVscGZ1bCwgYW5kIGNhbiBiZSBmb3VuZCBhdDogaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2JybXMvdmlnbmV0dGVzL2JybXNfbXVsdGl2YXJpYXRlLmh0bWwuDQoNCiMjIE1vZGVsIDENClRoZSBmaXJzdCBtb2RlbCBmaXQgd2FzIHRoZSBvbmUgZGVzY3JpYmVkIGFib3ZlLg0KYGBge3IgbjJvX21vZF9tdl8xLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KDQpiZl9uMm8gPC0gYmYobG9nKG4ybykgfiAxICsgDQogICAgICAgICAgICAgICAoMSB8IGEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKDEgfCBiIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgYyB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIGZhbWlseSA9IGdhdXNzaWFuKCkpDQoNCmJmX24yb2VxIDwtIGJmKGxvZyhuMm9fZXEpIH4gMSArIA0KICAgICAgICAgICAgICAgKDEgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICgxIHwgYiB8IFdTQTk6c3RhdGUpICsNCiAgICAgICAgICAgICAgICgxIHwgYyB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIGZhbWlseSA9IGdhdXNzaWFuKCkpDQoNCnByaW9ycyA8LSBjKA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibG9nbjJvIiksICMgY2VudGVyZWQgbmVhciBkYXRhIG1lYW4NCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3Iobm9ybWFsKDIsIDEpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCByZXNwID0gImxvZ24yb2VxIiksICMgY2VudGVyZWQgbmVhciBkYXRhIG1lYW4NCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJsb2duMm9lcSIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAicmVzY29yIiksDQogIHByaW9yKGxraigyKSwgY2xhc3MgPSAiY29yIikNCiAgKQ0KDQpuMm9fbW9kMSA8LSBicm0oYmZfbjJvICsgYmZfbjJvZXEgKyBzZXRfcmVzY29yKHJlc2NvciA9IFRSVUUpLA0KICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9tb2RlbCwNCiAgICAgICAgICAgICAgICBwcmlvciA9IHByaW9ycywNCiAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTksIG1heF90cmVlZGVwdGggPSAxNCksDQogICAgICAgICAgICAgICAgI3NhbXBsZV9wcmlvciA9ICJvbmx5IiwNCiAgICAgICAgICAgICAgICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gVFJVRSksDQogICAgICAgICAgICAgICAgc2VlZCA9IDE0NSwNCiAgICAgICAgICAgICAgICBjaGFpbnM9NCwgDQogICAgICAgICAgICAgICAgaXRlcj01MDAwLCANCiAgICAgICAgICAgICAgICBjb3Jlcz00KQ0KDQpzYXZlKG4yb19tb2QxLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpgYGANCg0KDQojIyMgU3VtbWFyaXplIGZpdA0KVGhlIHN1bW1hcmllcyBvZiB0aGUgZXN0aW1hdGVkIHBhcmFtZXRlcnMgYW5kIGtleSBITUMgY29udmVyZ2VuY2UgZGlhZ25vc3RpY3MgZm9yIHRoZSBmaXR0ZWQgbW9kZWwgYXJlIHByaW50ZWQgYmVsb3cuIFRoZXJlIHdlcmUgbm8gb2J2aW91cyBpc3N1ZXMgd2l0aCB0aGUgSE1DIHNhbXBsaW5nLiBBbGwgJFxoYXR7Un0kIHZhbHVlcyB3ZXJlIGxlc3MgdGhhbiAxLjAxIGFuZCBlZmZlY3RpdmUgc2FtcGxlIHNpemUgKCRFU1MkKSBjYWxjdWxhdGlvbnMgc3VnZ2VzdGVkIHRoYXQgdGhlIHBvc3RlcmlvciBjb250YWluZWQgYSBzdWZmaWNpZW50IG51bWJlciBvZiBlZmZlY3RpdmUgc2FtcGxlcyBmb3IgY29uZHVjdGluZyBpbmZlcmVuY2UuDQpgYGB7ciBwcmludF9tb2QxLCBlY2hvPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCg0KcHJpbnQobjJvX21vZDEsIHByaW9yID0gVCkNCmBgYA0KSW4gdGhlIHN1bW1hcnkgYWJvdmUsIHRoZSBlc3RpbWF0ZWQgc3RhbmRhcmQgZGV2aWF0aW9ucyBmb3IgdGhlIHZhcnlpbmcgZ3JvdXAgZWZmZWN0cyBvbiB0aGUgbWVhbiBiZWhhdmlvciBvZiB0aGUgZGlzc29sdmVkIE4yTyByZXNwb25zZSBzdWdnZXN0ZWQgZmFpcmx5IGxvdywgYnV0IG5vbi16ZXJvIHZhcmlhYmlsaXR5IGFjcm9zcyBlYWNoIG9mIHRoZSB0aHJlZSBsZXZlbHMuIFRoZSBzdGFuZGFyZCBkZXZpYXRpb25zIGVzdGltYXRlZCBmb3IgdGhlIHNhbWUgdmFyeWluZyBlZmZlY3RzIGZvciBlcXVpbGlicml1bSBOMk8gd2VyZSBhbHNvIHJlbGF0aXZlbHkgc21hbGwuIEZpbmFsbHksIG5vdGUgdGhlIHJlbGF0aXZlbHkgc21hbGwsIGJ1dCBwb3NpdGl2ZSByZXNpZHVhbCBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSB0d28gTjJPIHJlc3BvbnNlcy4gDQoNCkJlZm9yZSBpbnZlc3RpbmcgdG9vIG11Y2ggaW50byB0aGUgaW50ZXJwcmV0YXRpb24gb2YgdGhpcyBtb2RlbCwgaG93ZXZlciwgdGhlIG1vZGVsIGZpdCB3YXMgZXZhbHVhdGVkIGJlbG93IHVzaW5nIGEgc2VyaWVzIG9mIGdyYXBoaWNhbCBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBjaGVja3MgW1BQQzsgQEdlbG1hbl9ldGFsXzIwMTQ7IEBHZWxtYW5fZXRhbF8yMDIwLCBDaC4gMTFdLg0KDQojIyMgTW9kZWwgY2hlY2tzDQojIyMjIERpc3NvbHZlZCBOMk8NCkJlbG93IGFyZSBhIHNlcmllcyBvZiBwYW5lbHMgaWxsdXN0cmF0aW5nIGdyYXBoaWNhbCBQUENzIGZvciB0aGUgbG9nKE4yTykgY29tcG9uZW50IG9mIHRoZSBtb2RlbC4gVGhlIHRvcCBsZWZ0IHBhbmVsIGNvbXBhcmVzIGEgZGVuc2l0eSBwbG90IG9mIHRoZSBvYnNlcnZlZCBkYXRhIChibGFjayBsaW5lKSB0byBkZW5zaXR5IGxpbmVzIGRyYXduIGZvciAyMDAgc2FtcGxlcyBmcm9tIHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24gKFBQRDsgYmx1ZSBsaW5lcykgb2YgdGhlIGZpdHRlZCBtb2RlbC4gVGhlIHRvcCByaWdodCBwYW5lbCBzaW1pbGFybHkgY29tcGFyZXMgdGhlIGN1bXVsYXRpdmUgZGVuc2l0eSBkaXN0cmlidXRpb25zLiBUaGUgbGVmdCBtaWRkbGUgcGFuZWwgc2ltdWxhdGFuZW91c2x5IGNvbXBhcmVzIG1lYW5zIF92cy5fIHN0YW5kYXJkIGRldmlhdGlvbnMgZm9yIDEwMDAgZHJhd3MgZnJvbSB0aGUgUFBEIChibHVlIGRvdHMpIHRvIHRoZSBzYW1wbGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIChibGFjayBkb3QpLiBUaGUgcmlnaHQgbWlkZGxlIHBhbmVsIGNvbXBhcmVzIHNrZXduZXNzIF92cy5fIGt1cnRvc2lzIGZvciAxMDAwIGRyYXdzIGZyb20gdGhlIFBQRCB0byB0aGUgc2tld25lc3MgYW5kIGt1cnRvc2lzIHZhbHVlcyBjYWxjdWxhdGVkIGZvciB0aGUgb2JzZXJ2ZWQgZGF0YS4gVGhlIGJvdHRvbSBsZWZ0IHBhbmVsIGNvbXBhcmVzIG1heCBfdnMuXyBtaW4gdmFsdWVzIGZvciAxMDAwIGRyYXdzIGZyb20gdGhlIFBQRCB0byB0aGUgbWF4IGFuZCBtaW4gdmFsdWVzIG9mIHRoZSBzYW1wbGUgZGF0YS4gRmluYWxseSwgdGhlIGJvdHRvbSByaWdodCBwYW5lbCBzaG93cyB0aGUgb2JzZXJ2ZWQgX3ZzLl8gYXZlcmFnZSBwcmVkaWN0ZWQgdmFsdWVzIGZvciBlYWNoIG9ic2VydmF0aW9uIGluIHRoZSBzYW1wbGUuIFRoZSBhdmVyYWdlIHByZWRpY3RlZCB2YWx1ZXMgd2VyZSBjYWxjdWxhdGVkIGFzIHRoZSBtZWFuIHByZWRpY3Rpb24gZm9yIGVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIFBQRCBiYXNlZCBvbiAxMDAwIGRyYXdzLg0KYGBge3IgcHBjX24ybzEsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgbmRyYXdzID0gMjAwLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwNCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic2NhdHRlcl9hdmciLA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANClRoZSBnZW5lcmFsIHRha2Vhd2F5IGZyb20gdGhlIFBQQ3MgYWJvdmUgd2FzIHRoYXQgdGhlIG1vZGVsIHJlcGxpY2F0ZWQgdGhlIGNlbnRyYWwgdGVuZGVuY3kgb2YgdGhlIG9ic2VydmVkIGRhdGEgZmFpcmx5IHdlbGwsIGJ1dCBmYWlsZWQgdG8gc3VmZmljaWVudGx5IHJlcGxpY2F0ZSBvdGhlciBpbXBvcnRhbnQgYXNwZWN0cyBvZiB0aGUgZGlzdHJpYnV0aW9uLCBzdWNoIGFzIHNrZXduZXNzIGFuZCBrdXJ0b3Npcy4gVGhlIG9ic2VydmVkIF92cy5fIGF2ZXJhZ2UgcHJlZGljdGlvbnMgc2NhdHRlcnBsb3Qgc3VnZ2VzdGVkIHN1YnN0YW50aWFsIGhldGVyb3NjZWRhc3RpY2l0eSBpbiB0aGUgZXJyb3JzLiANCg0KVGhlIHNhbWUgY2hlY2tzIHdlcmUgcnVuIGJlbG93LCBidXQgZm9yIHRoZSB0ZXN0IHNldCBvZiA5NSBoZWxkLW91dCwgc2Vjb25kLXZpc2l0IGRhdGEgcG9pbnRzLiANCmBgYHtyIHBwY19uMm8xX3Rlc3QsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl90ZXN0LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICBuZXdkYXRhID0gZGZfdGVzdCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICBuZXdkYXRhID0gZGZfdGVzdCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICBuZXdkYXRhID0gZGZfdGVzdCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwNCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICBuZXdkYXRhID0gZGZfdGVzdCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICBuZXdkYXRhID0gZGZfdGVzdCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic2NhdHRlcl9hdmciLA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANClRoZSBwYXR0ZXJucyBpbiBtaXNmaXQgaW5kaWNhdGVkIGFib3ZlIGZvciB0aGUgcmUtdmlzaXQgZGF0YSB3ZXJlIHNpbWlsYXIgdG8gdGhlIHBhdHRlcm5zIGluZGljYXRlZCBpbiB0aGUgUFBDcyB3aXRoIHRoZSB0cmFpbmluZyBkYXRhLg0KDQojIyMjIEVxdWlsaWJyaXVtIE4yTw0KQmVsb3cgYXJlIFBQQ3MgZm9yIHRoZSBlcXVpbGlicml1bSBOMk8gY29tcG9uZW50IG9mIHRoZSBtb2RlbC4gQXMgd2l0aCB0aGUgZGlzc29sdmVkIE4yTyByZXNwb25zZSBhYm92ZSwgdGhlIG1vZGVsIGRpZCBhbiBPSyBqb2IgYXQgcmVwbGljYXRpbmcgdGhlIGNlbnRyYWwgdGVuZGVuY3ksIGJ1dCBwZXJmb3JtZWQgbGVzcyB3ZWxsIGF0IHJlcGxpY2F0aW5nIHNvbWUgaW1wb3J0YW50IGFzcGVjdHMgb2YgdGhlIG92ZXJhbGwgZGlzdHJpYnV0aW9uLiANCmBgYHtyIHBwY19uMm9lcTEsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZGVuc19vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwNCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANCg0KQmVsb3cgYXJlIHRoZSBzYW1lIFBQQ3MgZm9yIGVxdWlsaWJyaXVtIE4yTyBpbiB0aGUgcmUtdmlzaXQgc2l0ZXMuDQpgYGB7ciBwcGNfbjJvZXExX3Rlc3QsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kMSwNCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDEsIA0KICAgICAgICAgbmV3ZGF0YSA9IGRmX3Rlc3QsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMSwgDQogICAgICAgICBuZXdkYXRhID0gZGZfdGVzdCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QxLCANCiAgICAgICAgIG5ld2RhdGEgPSBkZl90ZXN0LA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KIyMjIyBCaXZhcmlhdGUNClRoZSBncmFwaGljYWwgY2hlY2sgYmVsb3cgY29tcGFyZXMgYml2YXJpYXRlIGRlbnNpdHkgY29udG91cnMgZXN0aW1hdGVkIGZyb20gdGhlIG9ic2VydmVkIGRhdGEgKGJsYWNrIGxpbmVzKSB0byBkZW5zaXR5IGNvbnRvdXJzIGVzdGltYXRlZCBmb3IgZWFjaCBvZiAyMCBkcmF3cyBmcm9tIHRoZSBQUEQuIFRoZSBtb2RlbCBhcHBlYXJlZCB0byBkbyBhIGdvb2Qgam9iIG9mIHJlcGxpY2F0aW5nIHRoZSBiaXZhcmlhdGUgbWVhbiwgYnV0IHdhcyBwb29yIGF0IHJlcHJlc2VudGluZyB0aGUgb3ZlcmFsbCBqb2ludCBkaXN0cmlidXRpb24uDQpgYGB7ciBwcGNfYml2MSwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSAyMCkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG4ybyksIHkgPSBsb2cobjJvX2VxKSkpICsNCiAgZ2VvbV9kZW5zaXR5XzJkKGFlcyh4ID0gbG9nbjJvLCANCiAgICAgICAgICAgICAgICAgICAgICB5ID0gbG9nbjJvZXEsIA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gLmRyYXcpLA0KICAgICAgICAgICAgICAgICAgYmlucyA9IDEwLA0KICAgICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIiwgDQogICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX2RlbnNpdHlfMmQoY29sb3IgPSAiYmxhY2siLCBiaW5zID0gMTApICsNCiAgeGxpbSgxLjI1LCAyLjc1KSArDQogIHlsaW0oMS4yNSwgMi43NSkgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpUaGUgc2FtZSBiaXZhcmlhdGUgY2hlY2sgaXMgc2hvd24gYmVsb3cgZm9yIHRoZSByZS12aXNpdCBkYXRhLg0KYGBge3IgcHBjX2JpdjFfdGVzdCwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDEucmRhIikNCmRmX3Rlc3QgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDEsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDIwKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2cobjJvKSwgeSA9IGxvZyhuMm9fZXEpKSkgKw0KICBnZW9tX2RlbnNpdHlfMmQoYWVzKHggPSBsb2duMm8sIA0KICAgICAgICAgICAgICAgICAgICAgIHkgPSBsb2duMm9lcSwgDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAuZHJhdyksDQogICAgICAgICAgICAgICAgICBiaW5zID0gMTAsDQogICAgICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiLCANCiAgICAgICAgICAgICAgICAgIGFscGhhID0gMC40KSArDQogIGdlb21fZGVuc2l0eV8yZChjb2xvciA9ICJibGFjayIsIGJpbnMgPSAxMCkgKw0KICB4bGltKDEuMjUsIDIuNzUpICsNCiAgeWxpbSgxLjI1LCAyLjc1KSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCiMjIyMgU2F0dXJhdGlvbg0KVGhlIGdyYXBoaWNhbCBQUENzIGJlbG93IHdlcmUgYWltZWQgYXQgZXZhbHVhdGluZyBob3cgd2VsbCB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsIGRpZCBhdCByZXByZXNlbnRpbmcgdGhlIG9ic2VydmVkIHNhdHVyYXRpb24gcmF0aW86IA0KJCROXzJPX3tkaXNzb2x2ZWR9Ok5fMk9fe2VxdWlsaWJyaXVtfSQkDQpUaGlzIHF1YW50aXR5IHdhcyBlc3RpbWF0ZWQgYXMgYSBkZXJpdmVkIHZhcmlhYmxlIGJ5IHNpbXBseSBkaXZpZGluZyB0aGUgTjJPIFBQRCBieSB0aGUgZXF1aWxpYnJpdW0gTjJPIFBQRC4gTGlrZXdpc2UsIHRoZSBwcm9wb3J0aW9uIG9mIHVuZGVyLXNhdHVyYXRlZCBsYWtlcyBpbiB0aGUgc2FtcGxlIHdhcyBlc3RpbWF0ZWQgYnkgc3VtbWluZyB0aGUgbnVtYmVyIG9mIGxha2VzIGZyb20gZWFjaCBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkcmF3IHdoZXJlaW4gdGhlIHJhdGlvIHdhcyA8IDEgYW5kIGRpdmlkaW5nIHRoYXQgbnVtYmVyIGJ5IHRoZSB0b3RhbCBudW1iZXIgb2YgbGFrZXMgaW4gdGhlIHNhbXBsZSwgd2hpY2ggd2FzIDk4NC4NCk92ZXJhbGwsIHRoZXNlIGNoZWNrcyBpbmRpY2F0ZWQgdGhhdCBwcm9wZXJseSByZXByZXNlbnRpbmcgdGhlIHRhaWxzIG9mIHRoZSBOMk8gYW5kIE4yTy1lcSBvYnNlcnZhdGlvbnMgd291bGQgbGlrZWx5IGJlIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBiZXR0ZXIgcmVwbGljYXRlIHRoZSBvYnNlcnZlZCBzYXR1cmF0aW9uIG1ldHJpY3MuIEZvciBleGFtcGxlLCB0aGUgbW9kZWwgZGlkIGEgcG9vciBqb2IgcmVwbGljYXRpbmcgdGhlIG9ic2VydmVkIHByb3BvcnRpb24gb2YgdW5kZXItc2F0dXJhdGVkIGxha2VzLCB1bmRlcmVzdGltYXRpbmcgaXQgYnkgbW9yZSB0aGFuIDEwIHBlcmNlbnRhZ2UgcG9pbnRzLCBvbiBhdmVyYWdlLg0KYGBge3IgcHBjX3NhdDEsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gc2F0X3ByZWQsIGdyb3VwID0gLmRyYXcpLCANCiAgICAgICAgICAgICAgIG4gPSAxMDI0LCANCiAgICAgICAgICAgICAgIGFkanVzdCA9IDEsDQogICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fZGVuc2l0eShuID0gMTAyNCwgYWRqdXN0ID0gMikgKw0KICB4bGltKDAsIDUpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHVzYXRfcHJlZCA9IGlmZWxzZShsb2duMm8gPCBsb2duMm9lcSwgMSwgMCkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3ByZWQgPSBzdW0odXNhdF9wcmVkKSAvIDk4NCkgJT4lDQogIGdncGxvdChhZXMoeCA9IHByb3BfcHJlZCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAwMSwgZmlsbCA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoZGF0YSA9IGRmX21vZGVsLCBtYXBwaW5nID0gYWVzKHhpbnRlcmNlcHQgPSBzdW0objJvIDwgbjJvX2VxKS85ODQpKSArDQogIHhsYWIoIlByb3BvcnRpb24gdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSwNCiAgICAgICAgIHNkX3lyZXAgPSBzZChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWVhbl95ID0gbWVhbihzYXRfcmF0aW8pLA0KICAgICAgICAgc2RfeSA9IHNkKHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzZF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lYW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHNkX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtaW5feXJlcCA9IG1pbihzYXRfcHJlZCksDQogICAgICAgICBtYXhfeXJlcCA9IG1heChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWluX3kgPSBtaW4oc2F0X3JhdGlvKSwNCiAgICAgICAgIG1heF95ID0gbWF4KHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtaW5feXJlcCwgeSA9IG1heF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1pbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gbWF4X3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSgucm93KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpKSAlPiUgDQogIGZpbHRlciguZHJhdyA9PSAxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQpUaGUgdG9wIGxlZnQgcGFuZWwsIGFib3ZlLCBpcyBhIGRlbnNpdHkgcGxvdCBvZiB0aGUgb2JzZXJ2ZWQgc2F0dXJhdGlvbiByYXRpbyAoYmxhY2sgbGluZSkgY29tcGFyZWQgdG8gYW4gZXN0aW1hdGUgdXNpbmcgNTAgZHJhd3MgZnJvbSB0aGUgbW9kZWwgKGJsdWUgbGluZXMpLiBUaGUgdG9wIHJpZ2h0IHBhbmVsIHNob3dzIHRoZSBvYnNlcnZlZCBwcm9wb3J0aW9uIG9mIHVuZGVyLXNhdHVyYXRlZCBsYWtlcyBjb21wYXJlZCB0byBhIG1vZGVsIGVzdGltYXRlIGJhc2VkIG9uIDEwMDAgZHJhd3MgZnJvbSB0aGUgUFBELiBUaGUgbGVmdCBtaWRkbGUgcGFuZWwgc2hvd3MgdGhlIG1lYW4gX3ZzLl8gc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBzYXR1cmF0aW9uIHJhdGlvIGZvciB0aGUgb2JzZXJ2ZWQgZGF0YSBjb21wYXJlZCB0byB0aGUgc2FtZSBlc3RpbWF0ZXMgZm9yIDUwMCBwb3N0ZXJpb3IgZHJhd3MgZnJvbSB0aGUgbW9kZWwncyBQUEQuIFRoZSByaWdodCBtaWRkbGUgcGFuZWwgc2hvd3MgdGhlIG1heCBfdnMuXyBtaW4gZm9yIHRoZSBzYW1wbGUgY29tcGFyZWQgdG8gNTAwIGRyYXdzIGZyb20gdGhlIG1vZGVsJ3MgUFBELiBGaW5hbGx5LCB0aGUgYm90dG9tIGxlZnQgcGFuZWwgc2hvd3MgdGhlIG9ic2VydmVkIF92cy5fIGF2ZXJhZ2UgcHJlZGljdGVkIHNhdHVyYXRpb24gcmF0aW8gZm9yIGFsbCA5ODQgbGFrZXMgc2FtcGxlZCBpbiB0aGUgZGF0YXNldC4NCg0KVGhlIHNhbWUgUFBDcyBhcmUgc2hvdyBiZWxvdyBmb3IgdGhlIHJldmlzaXQgZGF0YS4NCmBgYHtyIHBwY19zYXQxX3Rlc3QsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpkZl90ZXN0ICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSBzYXRfcHJlZCwgZ3JvdXAgPSAuZHJhdyksIA0KICAgICAgICAgICAgICAgbiA9IDEwMjQsIA0KICAgICAgICAgICAgICAgYWRqdXN0ID0gMSwNCiAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV9kZW5zaXR5KG4gPSAxMDI0LCBhZGp1c3QgPSAyKSArDQogIHhsaW0oMCwgNSkgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfdGVzdCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZSh1c2F0X3ByZWQgPSBpZmVsc2UobG9nbjJvIDwgbG9nbjJvZXEsIDEsIDApKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UocHJvcF9wcmVkID0gc3VtKHVzYXRfcHJlZCkgLyA5NSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHByb3BfcHJlZCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAwMSwgZmlsbCA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoZGF0YSA9IGRmX3Rlc3QsIG1hcHBpbmcgPSBhZXMoeGludGVyY2VwdCA9IHN1bShuMm8gPCBuMm9fZXEpLzk1KSkgKw0KICB4bGFiKCJQcm9wb3J0aW9uIHVuZGVyc2F0dXJhdGVkIHdhdGVyYm9kaWVzIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfdGVzdCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSwNCiAgICAgICAgIHNkX3lyZXAgPSBzZChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWVhbl95ID0gbWVhbihzYXRfcmF0aW8pLA0KICAgICAgICAgc2RfeSA9IHNkKHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzZF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lYW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHNkX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl90ZXN0ICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QxLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1pbl95cmVwID0gbWluKHNhdF9wcmVkKSwNCiAgICAgICAgIG1heF95cmVwID0gbWF4KHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtaW5feSA9IG1pbihzYXRfcmF0aW8pLA0KICAgICAgICAgbWF4X3kgPSBtYXgoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1pbl95cmVwLCB5ID0gbWF4X3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWluX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBtYXhfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX3Rlc3QgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDEsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ3JvdXBfYnkoLnJvdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSkgJT4lIA0KICBmaWx0ZXIoLmRyYXcgPT0gMSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzYXRfcmF0aW8pKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANClRoZSBjaGVja3MgYWJvdmUgaW5kaWNhdGVkIHRoYXQgdGhlIG1vZGVsIGRpZCBhIHNpbWlsYXJseSB1bmRlcndoZWxtaW5nIGpvYiBvZiByZXBsaWNhdGluZyBzb21lIGtleSBwcm9wZXJ0aWVzIG9mIHRoZSBzYXR1cmF0aW9uIG1ldHJpY3MgY2FsY3VsYXRlZCBmcm9tIHRoZSByZS12aXNpdCBkYXRhLg0KDQojIyMjIFItc3F1YXJlDQpCZWxvdywgdGhlIEJheWVzaWFuICRSXjIkIHZhbHVlcyBhcmUgcmVwb3J0ZWQgZm9yIGVhY2ggcmVhc3BvbnNlIGluIHRoZSBtb2RlbC4gDQpgYGB7ciByMl8xLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTR9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMS5yZGEiKQ0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDEsIHJlc3AgPSAibG9nbjJvIiwgY29yZXMgPSAxKSwgMykNCnJvdW5kKGJheWVzX1IyKG4yb19tb2QxLCByZXNwID0gImxvZ24yb2VxIiwgY29yZXMgPSAxKSwgMykNCmBgYA0KDQpUaGUgJFJeMiQgd2VyZSBhbHNvIGVzdGltYXRlZCBmb3IgdGhlIHJlLXZpc2l0IGRhdGEuDQpgYGB7ciByMl8xX3Rlc3QsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QxLnJkYSIpDQpyb3VuZChiYXllc19SMihuMm9fbW9kMSwgcmVzcCA9ICJsb2duMm8iLCBuZXdkYXRhID0gZGZfdGVzdCwgY29yZXMgPSAxKSwgMykNCnJvdW5kKGJheWVzX1IyKG4yb19tb2QxLCByZXNwID0gImxvZ24yb2VxIiwgbmV3ZGF0YSA9IGRmX3Rlc3QsIGNvcmVzID0gMSksIDMpDQpgYGANCg0KIyMgTW9kZWwgMg0KSW4gYW4gYXR0ZW1wdCB0byBiZXR0ZXIgZml0IHRoZSBvYnNlcnZlZCBkYXRhLCB0aGUgbmV4dCBtb2RlbCBpbmNsdWRlZCBkaXN0cmlidXRpb25hbCBzdWItbW9kZWxzIHRvIGFsbG93IGZvciBoZXRlcm9nZW5lb3VzIHZhcmlhbmNlcyBmb3IgZWFjaCByZXNwb25zZSBjb25kaXRpb25hbCBvbiB0aGUgc3VydmV5IGRlc2lnbiBzdHJ1Y3R1cmUuDQpgYGB7ciBuMm9fbW9kXzIsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmJmX24ybyA8LSBiZihsb2cobjJvKSB+IDEgKw0KICAgICAgICAgICAgICAgKDEgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICgxIHwgYiB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IGMgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBzaWdtYSB+IDEgKw0KICAgICAgICAgICAgICAgKDEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwgDQogICAgICAgICAgICAgZmFtaWx5ID0gZ2F1c3NpYW4oKSkNCg0KYmZfbjJvZXEgPC0gYmYobG9nKG4yb19lcSkgfiAxICsNCiAgICAgICAgICAgICAgICAgKDEgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICAgKDEgfCBiIHwgV1NBOTpzdGF0ZSkgKw0KICAgICAgICAgICAgICAgICAoMSB8IGMgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBzaWdtYSB+IDEgKw0KICAgICAgICAgICAgICAgKDEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KDQpwcmlvcnMgPC0gYygNCiAgcHJpb3Iobm9ybWFsKDIsIDEpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoLTEsIDIpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgyLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJsb2duMm9lcSIpLCANCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJsb2duMm9lcSIpLA0KICBwcmlvcihub3JtYWwoLTEsIDIpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm9lcSIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm9lcSIpLA0KICANCiAgcHJpb3IobGtqKDIpLCBjbGFzcyA9ICJyZXNjb3IiKSwNCiAgcHJpb3IobGtqKDIpLCBjbGFzcyA9ICJjb3IiKQ0KICApDQoNCm4yb19tb2QyIDwtIGJybShiZl9uMm8gKyBiZl9uMm9lcSArIHNldF9yZXNjb3IocmVzY29yID0gVFJVRSksDQogICAgICAgICAgICAgICAgZGF0YSA9IGRmX21vZGVsLCANCiAgICAgICAgICAgICAgICBwcmlvciA9IHByaW9ycywNCiAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjk3NSwgbWF4X3RyZWVkZXB0aCA9IDEyKSwNCiAgI3NhbXBsZV9wcmlvciA9ICJvbmx5IiwNCiAgc2F2ZV9wYXJzID0gc2F2ZV9wYXJzKGFsbCA9IFRSVUUpLA0KICBzZWVkID0gODQ1MTIsDQogIGNoYWlucz00LCANCiAgaXRlcj01MDAwLCANCiAgY29yZXM9NCkNCg0Kc2F2ZShuMm9fbW9kMiwgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMi5yZGEiKQ0KYGBgDQoNCiMjIyBTdW1tYXJpemUgZml0DQpUaGUgc3VtbWFyaWVzIG9mIHRoZSBlc3RpbWF0ZWQgcGFyYW1ldGVycyBhbmQga2V5IEhNQyBjb252ZXJnZW5jZSBkaWFnbm9zdGljcyBmb3IgdGhlIGZpdHRlZCBtb2RlbCBhcmUgcHJpbnRlZCBiZWxvdy4gDQpgYGB7ciBwcmludF9tb2QyLCBlY2hvPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDIucmRhIikNCg0KcHJpbnQobjJvX21vZDIsIHByaW9yID0gVCkNCmBgYA0KRnJvbSB0aGUgc3VtbWFyeSBhYm92ZSwgbm90ZSB0aGUgbW9kZXJhdGUgYW5kIHBvc2l0aXZlIHJlc2lkdWFsIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHR3byBOMk8gcmVzcG9uc2VzLiBUaGUgZXN0aW1hdGVkIHN0YW5kYXJkIGRldmlhdGlvbnMgZm9yIHRoZSB2YXJ5aW5nIGdyb3VwIGVmZmVjdHMgb24gdGhlIG1lYW4gYmVoYXZpb3Igb2YgdGhlIGRpc3NvbHZlZCBOMk8gcmVzcG9uc2Ugc3VnZ2VzdGVkIGZhaXJseSBsb3csIGJ1dCBub24temVybyB2YXJpYWJpbGl0eSBhY3Jvc3MgZWFjaCBvZiB0aGUgdGhyZWUgbGV2ZWxzLiBUaGUgc3RhbmRhcmQgZGV2aWF0aW9ucyBlc3RpbWF0ZWQgZm9yIHRoZSBzYW1lIHZhcnlpbmcgZWZmZWN0cyBmb3IgZXF1aWxpYnJpdW0gTjJPIHdlcmUgYWxzbyByZWxhdGl2ZWx5IHNtYWxsLiBIb3dldmVyLCBiZWZvcmUgaW52ZXN0aW5nIHRvbyBtdWNoIGludG8gdGhlIGludGVycHJldGF0aW9uIG9mIHRoZXNlIHJlc3VsdHMsIHRoZSBtb2RlbCBmaXQgd2FzIGZ1cnRoZXIgZXZhbHVhdGVkIGJlbG93IHVzaW5nIGEgc2VyaWVzIG9mIGdyYXBoaWNhbCBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBjaGVja3MgKFBQQ3MpLg0KDQojIyMgTW9kZWwgY2hlY2tzDQpCZWxvdyB0aGUgc2FtZSBQUENzIHdlcmUgcGVyZm9ybWVkIGFzIHdpdGggdGhlIGluaXRpYWwgbW9kZWwgKHNlZSBhYm92ZSBmb3IgbW9yZSBkZXRhaWxzIG9uIGVhY2ggcGFuZWwpLiANCiMjIyMjIERpc3NvbHZlZCBOMk8NClRob3VnaCB0aGUgY2hlY2tzIGJlbG93IHN1Z2dlc3Qgc29tZSBpbXByb3ZlbWVudCBpbiByZXBsaWNhdGluZyB0aGUgdGFpbHMgb2YgdGhlIG9ic2VydmVkIGRhdGEsIHRoaXMgbW9kZWwgZGlkIGEgcG9vcmVyIGpvYiBhdCByZXBsaWNhdGluZyBjZW50cmFsIHRlbmRlbmN5Lg0KYGBge3IgcHBjX24ybzIsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QyLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxpbSgtNSwgNSkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImVjZGZfb3ZlcmxheSIsDQogICAgICAgICBuZHJhd3MgPSAyMDAsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsaW0oLTUsIDUpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtZWFuIiwgInNkIiksDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDIsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygia3VydG9zaXMiLCAic2tld25lc3MiKSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDIsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIEVxdWlsaWJyaXVtIE4yTw0KVGhlIGNoZWNrcyBiZWxvdyBzdWdnZXN0IHRoaXMgbW9kZWwgb2ZmZXJlZCBubyBpbXByb3ZlbWVudCB1cG9uIHRoZSBpbml0aWFsIG1vZGVsIGZvciBlcXVpbGlicml1bSBOMk8uIFRoaXMgbW9kZWwgYWxzbyBhcHBlYXJlZCB0byBkbyBhIHBvb3JlciBqb2Igb2YgcmVwbGljYXRpbmcgdGhlIG1lYW4gYW5kIG92ZXJhbGwgc3RhbmRhcmQgZGV2aWF0aW9uIGNvbXBhcmVkIHRvIHRoZSBpbml0aWFsIG1vZGVsLg0KYGBge3IgcHBjX24yb2VxMiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDIucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJkZW5zX292ZXJsYXkiLA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKEVxdWlsaWJyaXVtIE4iWzJdLCJPKSIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhFcXVpbGlicml1bSBOIlsyXSwiTykiKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDIsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QyLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMiwgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic2NhdHRlcl9hdmciLCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgQml2YXJpYXRlDQpUaGlzIGNoZWNrIHBlcmhhcHMgc3VnZ2VzdGVkIGFuIGltcHJvdmVtZW50IHdpdGggcmVnYXJkIHRvIHJlcGxpY2F0aW5nIHRoZSBqb2ludCBkZW5zaXR5LiBIb3dldmVyLCB0aGUgcHJlZGljdGlvbnMgd2VyZSBzdGlsbCBjbGVhcmx5IG92ZXItZGlzcGVyc2VkIHJlbGF0aXZlIHRvIHRoZSBvYnNlcnZhdGlvbnMuDQpgYGB7ciBwcGNfYml2MiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDIucmRhIikNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QyLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSAyMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2cobjJvX29icyksIHkgPSBsb2cobjJvZXFfb2JzKSkpICsNCiAgZ2VvbV9kZW5zaXR5XzJkKGFlcyh4ID0gbG9nbjJvLCANCiAgICAgICAgICAgICAgICAgICAgICB5ID0gbG9nbjJvZXEsIA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gLmRyYXcpLA0KICAgICAgICAgICAgICAgICAgYmlucyA9IDEwLA0KICAgICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIiwgDQogICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX2RlbnNpdHlfMmQoY29sb3IgPSAiYmxhY2siLCBiaW5zID0gMTApICsNCiAgeGxpbSgxLjI1LCAyLjc1KSArDQogIHlsaW0oMS4yNSwgMi43NSkgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQojIyMjIFNhdHVyYXRpb24NClRoZSBQUENzIGZvciB0aGUgc2F0dXJhdGlvbiBtZXRyaWNzIGJlbG93IGluZGljYXRlZCB0aGF0IGluY2x1ZGluZyB0aGUgZGlzdHJpYnV0aW9uYWwgbW9kZWxzIHdhcyBwZXJoYXBzIGFuIGltcHJvdmVtZW50IG9uIHRoZSBpbml0aWFsIG1vZGVsIGluIHNvbWUgYXNwZWN0czsgaW4gcGFydGljdWxhciwgdGhlIGJpYXMgaW4gdGhlIHByZWRpY3RlZCBwcm9wb3J0aW9uIG9mIHVuZGVyLXNhdHVyYXRlZCBsYWtlcyB3YXMgc3Vic3RhbnRpYWxseSBkZWNyZWFzZWQuIEhvd2V2ZXIsIHRoZXJlIGFwcGVhcmVkIHRvIHN0aWxsIGJlIGlzc3VlcyBpbiByZXBsaWNhdGluZyB0aGUgdGFpbHMgYXMgd2VsbCBhcyBpc3N1ZXMgd2l0aCBjZW50cmFsIHRlbmRlbmN5Lg0KYGBge3IgcHBjX3NhdDIsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QyLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMiwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gc2F0X3ByZWQsIGdyb3VwID0gLmRyYXcpLCANCiAgICAgICAgICAgICAgIG4gPSAxMDI0LCANCiAgICAgICAgICAgICAgIGFkanVzdCA9IDEsDQogICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fZGVuc2l0eShuID0gMTAyNCwgYWRqdXN0ID0gMikgKw0KICB4bGltKDAsIDUpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QyLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHVzYXRfcHJlZCA9IGlmZWxzZShsb2duMm8gPCBsb2duMm9lcSwgMSwgMCkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3ByZWQgPSBzdW0odXNhdF9wcmVkKSAvIDk4NCkgJT4lDQogIGdncGxvdChhZXMoeCA9IHByb3BfcHJlZCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAwMSwgZmlsbCA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoZGF0YSA9IGRmX21vZGVsLCBtYXBwaW5nID0gYWVzKHhpbnRlcmNlcHQgPSBzdW0objJvIDwgbjJvX2VxKS85ODQpKSArDQogIHhsYWIoIlByb3BvcnRpb24gdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMiwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSwNCiAgICAgICAgIHNkX3lyZXAgPSBzZChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWVhbl95ID0gbWVhbihzYXRfcmF0aW8pLA0KICAgICAgICAgc2RfeSA9IHNkKHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzZF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lYW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHNkX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMiwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtaW5feXJlcCA9IG1pbihzYXRfcHJlZCksDQogICAgICAgICBtYXhfeXJlcCA9IG1heChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWluX3kgPSBtaW4oc2F0X3JhdGlvKSwNCiAgICAgICAgIG1heF95ID0gbWF4KHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtaW5feXJlcCwgeSA9IG1heF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1pbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gbWF4X3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMiwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSgucm93KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpKSAlPiUgDQogIGZpbHRlciguZHJhdyA9PSAxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIFItc3F1YXJlDQpSZWxhdGl2ZSB0byBtb2RlbCAxLCB0aGVyZSB3YXMgYSBzdWJzdGFudGlhbCBkZWNyZWFzZSBpbiB0aGUgJFJeMiQgZXN0aW1hdGUgZm9yIHRoZSBkaXNzb2x2ZWQgTjJPIGNvbXBvbmVudCBvZiB0aGlzIG1vZGVsLiBUaGUgZXN0aW1hdGUgZm9yIHRoZSBlcXVpbGlicml1bSBOMk8tZXEgY29tcG9uZW50IHdhcyBzaW1pbGFyIHRvIHRoZSBtb2RlbCAxLiANCmBgYHtyIHIyXzIsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QyLnJkYSIpDQpyb3VuZChiYXllc19SMihuMm9fbW9kMiwgcmVzcCA9ICJsb2duMm8iLCBjb3JlcyA9IDEpLCAzKSANCnJvdW5kKGJheWVzX1IyKG4yb19tb2QyLCByZXNwID0gImxvZ24yb2VxIiwgY29yZXMgPSAxKSwgMykNCmBgYA0KDQojIyBNb2RlbCAzDQpJbiB0aGUgbmV4dCBtb2RlbCwgd2UgdXNlZCBjb3ZhcmlhdGVzIHRvIHRyeSB0byBpbXByb3ZlIHRoZSBmaXQuIFRoZSBjYXRlZ29yaWNhbCB2ZXJzaW9uIG9mIHRoZSBOTzMgY292YXJpYXRlIHdhcyB1c2VkIGFzIGEgbW9ub3RvbmljIG9yZGluYWwgcHJlZGljdG9yIGluIHRoZSBkaXNzb2x2ZWQgTjJPIGNvbXBvbmVudCBvZiB0aGUgbW9kbC4gRm9yIHRoZSBlcXVsaWJyaXVtIE4yTyBjb21wb25lbnQsIHdlIGluY2x1ZGVkIHN1cmZhY2UgdGVtcGVyYXR1cmUgYW5kIGxvZy10cmFuc2Zvcm1lZCBlbGV2YXRpb24sIGFsb25nIHdpdGggdGhlaXIgaW50ZXJhY3Rpb24uIFRoZSBtb2RlbHMgYWxzbyByZXRhaW5lZCB0aGUgZGlzdHJpYnV0aW9uYWwgc3BlY2lmaWNhdGlvbnMgaW5jbHVkZWQgaW4gbW9kZWwgMiBhYm92ZS4NCmBgYHtyIG4yb19tb2RfMywgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KYmZfbjJvIDwtIGJmKGxvZyhuMm8pIH4gbW8obm8zX2NhdCkgKw0KICAgICAgICAgICAgICAgc3VyZnRlbXAgKw0KICAgICAgICAgICAgICAgKG1vKG5vM19jYXQpIHwgYSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAobW8obm8zX2NhdCkgfCBiIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgYyB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIHNpZ21hIH4gMSArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLCANCiAgICAgICAgICAgICBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KDQpiZl9uMm9lcSA8LSBiZihsb2cobjJvX2VxKSB+IHN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgICAgbG9nX2VsZXYgKw0KICAgICAgICAgICAgICAgICBzdXJmdGVtcDpsb2dfZWxldiArDQogICAgICAgICAgICAgICAgICgxIHwgYSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAgICgxIHwgYiB8IFdTQTk6c3RhdGUpICsNCiAgICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgc2lnbWEgfiAxICsNCiAgICAgICAgICAgICAgICgxIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgZmFtaWx5ID0gZ2F1c3NpYW4oKSkNCg0KcHJpb3JzIDwtIGMoDQogIHByaW9yKG5vcm1hbCgyLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3Iobm9ybWFsKC0xLCAyKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKG5vcm1hbCgtMSwgMiksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gInJlc2NvciIpLA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gImNvciIpDQogICkNCg0KbjJvX21vZDMgPC0gYnJtKGJmX24ybyArIGJmX24yb2VxICsgc2V0X3Jlc2NvcihyZXNjb3IgPSBUUlVFKSwNCiAgICAgICAgICAgICAgICBkYXRhID0gZGZfbW9kZWwsIA0KICAgICAgICAgICAgICAgIHByaW9yID0gcHJpb3JzLA0KICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTc1LCBtYXhfdHJlZWRlcHRoID0gMTIpLA0KICAjc2FtcGxlX3ByaW9yID0gIm9ubHkiLA0KICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gVFJVRSksDQogIHNlZWQgPSA5ODQ1NiwNCiAgY2hhaW5zPTQsIA0KICBpdGVyPTUwMDAsIA0KICBjb3Jlcz00KQ0KDQpzYXZlKG4yb19tb2QzLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QzLnJkYSIpDQpgYGANCg0KIyMjIFN1bW1hcml6ZSBmaXQNClRoZSBmaXR0ZWQgcGFyYW1ldGVycyBhbmQgTUNNQyBkaWFnbm9zdGljcyBhcmUgYmVsb3cuDQpgYGB7ciBwcmludF9tb2QzLCBlY2hvPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDMucmRhIikNCg0KcHJpbnQobjJvX21vZDMsIHByaW9yID0gVCkNCmBgYA0KDQojIyMgTW9kZWwgY2hlY2tzDQojIyMjIERpc3NvbHZlZCBOMk8NClRoZSBQUENzIGJlbG93IGluZGljYXRlZCBhIGJldHRlciBmaXQgY29tcGFyZWQgdG8gdGhlIHByZXZpb3VzIG1vZGVscy4gVGhlIGNlbnRyYWwgdGVuZGVuY3kgYW5kIHRhaWwgYmVoYXZpb3IgbG9va2VkIHRvIGJlIHJlYXNvbmFibHkgcmVwbGljYXRlZCBieSBjb21wYXJpc29uLiBIb3dldmVyLCB0aGUgb2JzZXJ2ZWQgX3ZzLl8gcHJlZGljdGVkIHBsb3Qgc3VnZ2VzdGVkIHRoYXQgbGFyZ2VyIG92ZXJzZXJ2ZWQgdmFsdWVzIHdlcmUgYmVpbmcgc3lzdGVtYXRpY2FsbHkgdW5kZXJlc3RpbWF0ZWQuDQpgYGB7ciBwcGNfZnVsbF9jaGVja3NfbW9kX24ybzMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QzLnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kMywgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxpbSgwLCA1KSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMywgDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImVjZGZfb3ZlcmxheSIsDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxpbSgwLCA1KSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDMsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygia3VydG9zaXMiLCAic2tld25lc3MiKSwgIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic2NhdHRlcl9hdmciLCAgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIEVxdWlsaWJyaXVtIE4yTw0KVGhlIFBQQ3MgYmVsb3cgaW5kaWNhdGVkIHRoYXQgdGhpcyBtb2RlbCBhcHBlYXJlZCB0byBiZSBhbiBpbXByb3ZlbWVudCBmb3IgZXF1aWxpYnJpdW0gTjJPIGFzIHdlbGwuIEhvd2V2ZXIsIHNvbWUgY2hlY2tzIChlLmcuLCBza2V3bmVzcykgc3VnZ2VzdGVkIHNvbWUgcm9vbSBmb3IgYWRkaXRpb25hbCBpbXByb3ZlbWVudC4NCmBgYHtyIHBwY19mdWxsX2NoZWNrc19tb2RfbjJvZXEzLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMy5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KcHBfY2hlY2sobjJvX21vZDMsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsIA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKEVxdWlsaWJyaXVtIE4iWzJdLCJPKSIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kMywgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwgDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coRXF1aWxpYnJpdW0gTiJbMl0sIk8pIikpKSArIA0KICB5bGFiKCJjdW11bGF0aXZlIGRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDMsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtZWFuIiwgInNkIiksICANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMywgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kMywgDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2QzLCANCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsICANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgQml2YXJpYXRlDQpUaGUgY2hlY2sgZm9yIHRoZSBqb2ludCBkaXN0cmlidXRpb24gYmVsb3cgYWxzbyBzdWdnZXN0ZWQgYW4gaW1wcm92ZW1lbnQgdXAgdGhlIHByZXZpb3VzIG1vZGVscy4NCmBgYHtyIHBwY19idl9jaGVja19tb2RfbjJvMywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDMucmRhIikNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QzLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSAyMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2cobjJvX29icyksIHkgPSBsb2cobjJvZXFfb2JzKSkpICsNCiAgZ2VvbV9kZW5zaXR5XzJkKGFlcyh4ID0gbG9nbjJvLCANCiAgICAgICAgICAgICAgICAgICAgICB5ID0gbG9nbjJvZXEsIA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gLmRyYXcpLA0KICAgICAgICAgICAgICAgICAgYmlucyA9IDEwLA0KICAgICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIiwgDQogICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX2RlbnNpdHlfMmQoY29sb3IgPSAiYmxhY2siLCBiaW5zID0gMTApICsNCiAgeGxpbSgxLjI1LCAyLjc1KSArDQogIHlsaW0oMS4yNSwgMi43NSkgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQojIyMjIFNhdHVyYXRpb24NClRoaXMgbW9kZWwgbG9va2VkIHRvIGJlIGFuIGltcHJvdmVtZW50IHdpdGggcmVnYXJkIHRvIHRoZSBQUENzIGZvciB0aGUgc2F0dXJhdGlvbiBtZXRyaWNzLiBIb3dldmVyLCB0aGUgcHJvcG9ydGlvbiBvZiB1bmRlci1zYXR1cmF0ZWQgbGFrZXMgcmVtYWluZWQgYmlhc2VkIGxvdyBhbmQgb3RoZXIgY2hlY2tzIGluZGljYXRlZCB0aGF0IGZ1cnRoZXIgaW1wcm92ZW1lbnRzIHdvdWxkIGJlIGlkZWFsLg0KYGBge3IgcHBjX3NhdF9jaGVja19tb2RfbjJvMywgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDMucmRhIikNCmdyaWQuYXJyYW5nZSgNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2QzLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX2RlbnNpdHkoYWVzKHggPSBzYXRfcHJlZCwgZ3JvdXAgPSAuZHJhdyksIA0KICAgICAgICAgICAgICAgbiA9IDEwMjQsIA0KICAgICAgICAgICAgICAgYWRqdXN0ID0gMSwNCiAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV9kZW5zaXR5KG4gPSAxMDI0LCBhZGp1c3QgPSAyKSArDQogIHhsaW0oMCwgNSkgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDMsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUodXNhdF9wcmVkID0gaWZlbHNlKGV4cChsb2duMm8pIDwgZXhwKGxvZ24yb2VxKSwgMSwgMCkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3ByZWQgPSBzdW0odXNhdF9wcmVkKSAvIDk4NCkgJT4lDQogIGdncGxvdChhZXMoeCA9IHByb3BfcHJlZCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAwMSwgZmlsbCA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoZGF0YSA9IGRmX21vZGVsLCBtYXBwaW5nID0gYWVzKHhpbnRlcmNlcHQgPSBzdW0objJvIDwgbjJvX2VxKS85ODQpKSArDQogIHhsYWIoIlByb3BvcnRpb24gdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMywgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSwNCiAgICAgICAgIHNkX3lyZXAgPSBzZChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWVhbl95ID0gbWVhbihzYXRfcmF0aW8pLA0KICAgICAgICAgc2RfeSA9IHNkKHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzZF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lYW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHNkX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMywgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtaW5feXJlcCA9IG1pbihzYXRfcHJlZCksDQogICAgICAgICBtYXhfeXJlcCA9IG1heChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWluX3kgPSBtaW4oc2F0X3JhdGlvKSwNCiAgICAgICAgIG1heF95ID0gbWF4KHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtaW5feXJlcCwgeSA9IG1heF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1pbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gbWF4X3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kMywgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBncm91cF9ieSgucm93KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpKSAlPiUgDQogIGZpbHRlciguZHJhdyA9PSAxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIFItc3F1YXJlDQpUaGUgJFJeMiQgZXN0aW1hdGVzIGZvciB0aGlzIG1vZGVsIGFyZSBiZWxvdyBhbmQgc3VnZ2VzdGVkIHN1YnN0YW50aWFsIGltcHJvdmVtZW50cyBvbiB0aGUgcHJldmlvdXMgbW9kZWxzLg0KYGBge3IgcjJfbW9kX24ybzMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2QzLnJkYSIpDQpyb3VuZChiYXllc19SMihuMm9fbW9kMywgcmVzcCA9ICJsb2duMm8iLCBjb3JlcyA9IDEpLCAzKSANCnJvdW5kKGJheWVzX1IyKG4yb19tb2QzLCByZXNwID0gImxvZ24yb2VxIiwgY29yZXMgPSAxKSwgMykNCmBgYA0KDQojIyMgQ292YXJpYXRlIGVmZmVjdHMNCkJlbG93IGFyZSBwbG90cyBpbGx1c3RyYXRpbmcgdGhlIG1vZGVsZWQgZWZmZWN0cyBvZiBjb3ZhcmlhdGVzIG9uIGJvdGggTjJPIGFuZCBlcXVpbGlicml1bSBOMk8uDQojIyMjIE4yTw0KVGhlIGNvbmRpdGlvbmFsIGVmZmVjdHMgcGxvdHMgYmVsb3cgZm9yIE4yTyBpbGx1c3RyYXRlIGEgcG9zaXRpdmUsIG1vbm90b25pYywgYW5kIG5vbi1saW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gTk8zIGFuZCBOMk87IGFuZCBhIG5lZ2F0aXZlLCBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gc3VyZmFjZSB0ZW1wZXJhdHVyZSBhbmQgTjJPLg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19tb2RfbjJvMywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0zfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDMucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kMywgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJubzNfY2F0IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24ybyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygic3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLCANCiAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICBuY29sID0gMikNCg0Kcm0ocDEsIHAyKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCB0b3AgPSB0ZXh0X2dyb2IoIk4yTzogY29uZGl0aW9uYWwgZWZmZWN0cyIsIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpKQ0KYGBgDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpUaGUgbW9kZWxlZCBlZmZlY3RzIGJlbG93IGZvciB0aGUgZXF1aWxpYnJpdW0gTjJPIGNvbXBvbmVudCBvZiB0aGUgbW9kZWwgaWxsdXN0cmF0ZWQgYSBuZWdhdGl2ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBlcXVpbGlicml1bSBOMk8gYW5kIGJvdGggcHJlZGljdG9ycyBhbmQgYW4gaW50ZXJhY3Rpb24gc3VjaCB0aGF0IHRoZSBzdXJmYWNlIHRlbXBlcmF0dXJlIGVmZmVjdCBiZWNhbWUgc2xpZ2h0bHkgc3RlZXBlciBhdCBsb3dlciBlbGV2YXRpb25zLg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19tb2RfbjJvZXEzLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTN9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kMy5yZGEiKQ0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kMywgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoImxvZ19lbGV2OnN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24yb2VxIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJzdXJmdGVtcDpsb2dfZWxldiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIHRvcCA9IHRleHRfZ3JvYigiRXF1aWxpYnJpdW0gTjJPOiBjb25kaXRpb25hbCBlZmZlY3RzIiwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpDQpgYGANCg0KIyMgTW9kZWwgNA0KSW4gdGhlIG5leHQgbW9kZWwsIGNvdmFyaWF0ZSB0ZXJtcyB3ZXJlIGFsc28gaW5jbHVkZWQgaW4gdGhlICRcc2lnbWEkIGNvbXBvbmVudHMgb2YgYm90aCBtb2RlbHMgaW4gb3JkZXIgdG8gdHJ5IHRvIGJldHRlciBjYXB0dXJlIHJlbWFpbmluZyBoZXRlcm9nZW5laXR5IGluIHRoZSB2YXJpYW5jZXMgb2YgYm90aCBOMk8gYW5kIE4yTy1lcS4NCmBgYHtyIG4yb19tb2RfbXZfNCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KYmZfbjJvIDwtIGJmKGxvZyhuMm8pIH4gbW8obm8zX2NhdCkgKw0KICAgICAgICAgICAgICAgc3VyZnRlbXAgKw0KICAgICAgICAgICAgICAgKG1vKG5vM19jYXQpIHwgYSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAobW8obm8zX2NhdCkgfCBiIHwgV1NBOTpzdGF0ZSkgKyANCiAgICAgICAgICAgICAgICgxIHwgYyB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIHNpZ21hIH4gbW8obm8zX2NhdCkgKw0KICAgICAgICAgICAgICAgc3VyZnRlbXAgKw0KICAgICAgICAgICAgICAgKDEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwgDQogICAgICAgICAgICAgZmFtaWx5ID0gZ2F1c3NpYW4oKSkNCg0KYmZfbjJvZXEgPC0gYmYobG9nKG4yb19lcSkgfiBzdXJmdGVtcCArDQogICAgICAgICAgICAgICAgIGxvZ19lbGV2ICsNCiAgICAgICAgICAgICAgICAgc3VyZnRlbXA6bG9nX2VsZXYgKw0KICAgICAgICAgICAgICAgICAoMSB8IGEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgICAoMSB8IGIgfCBXU0E5OnN0YXRlKSArDQogICAgICAgICAgICAgICAgICgxIHwgYyB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIHNpZ21hIH4gc3VyZnRlbXAgKw0KICAgICAgICAgICAgICAgbG9nX2VsZXYgKw0KICAgICAgICAgICAgICAgKDEgfCBXU0E5KSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBXU0E5OnN0YXRlOnNpemVfY2F0KSwNCiAgICAgICAgICAgICBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KDQpwcmlvcnMgPC0gYygNCiAgcHJpb3Iobm9ybWFsKDIsIDEpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gImIiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihleHBvbmVudGlhbCgyKSwgY2xhc3MgPSAic2QiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoLTEsIDIpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKG5vcm1hbCgtMSwgMiksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gInJlc2NvciIpLA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gImNvciIpDQogICkNCg0KbjJvX21vZDQgPC0gYnJtKGJmX24ybyArIGJmX24yb2VxICsgc2V0X3Jlc2NvcihyZXNjb3IgPSBUUlVFKSwNCiAgICAgICAgICAgICAgICBkYXRhID0gZGZfbW9kZWwsIA0KICAgICAgICAgICAgICAgIHByaW9yID0gcHJpb3JzLA0KICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTc1LCBtYXhfdHJlZWRlcHRoID0gMTIpLA0KICAjc2FtcGxlX3ByaW9yID0gIm9ubHkiLA0KICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gVFJVRSksDQogIHNlZWQgPSAxNTg1MSwNCiAgY2hhaW5zPTQsIA0KICBpdGVyPTUwMDAsIA0KICBjb3Jlcz00KQ0KDQpzYXZlKG4yb19tb2Q0LCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQpgYGANCg0KIyMjIFN1bW1hcml6ZSBmaXQNCkJlbG93IGlzIGEgc3VtbWFyeSBvZiB0aGUgZml0dGVkIHBhcmFtZXRlcnMgYWxvbmcgd2l0aCBzb21lIGNvbnZlcmdlbmNlIGRpYWdub3N0aWNzLg0KYGBge3IgcHJpbnRfbW9kNCwgZWNobz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQoNCnByaW50KG4yb19tb2Q0LCBwcmlvciA9IFQsIGRpZ2l0cyA9IDMpDQpgYGANCg0KIyMjIE1vZGVsIGNoZWNrcw0KQWdhaW4sIHRoZSBzYW1lIFBQQ3Mgd2VyZSBlbXBsb3llZCBmb3IgdGhpcyBtb2RlbCBhcyBhYm92ZS4NCiMjIyMgRGlzc29sdmVkIE4yTw0KQWdhaW4sIHRoaXMgbW9kZWwgYXBwZWFyZWQgdG8gYmUgYW4gaW1wcm92ZW1lbnQgb24gdGhlIHByZXZpb3VzIG1vZGVsLCBwYXJ0aWN1bGFybHkgd2l0aCByZWdhcmQgdG8gdGhlIG1vcmUgY29uc3RhbnQgdmFyaWFuY2UgaW5kaWNhdGVkIGluIHRoZSBvYnNlcnZlZCBfdnMuXyBwcmVkaWN0ZWQgcGxvdCAoYm90dG9tLCByaWdodCBwYW5lbCkuDQpgYGB7ciBwcGNfZnVsbF9jaGVja3NfbW9kX24ybzQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kNCwgDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBuc2FtcGxlcyA9IDQwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kNCwgDQogICAgICAgICBuZHJhd3MgPSAyMDAsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gImVjZGZfb3ZlcmxheSIsDQogICAgICAgICBuc2FtcGxlcyA9IDQwLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykiKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kNCwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDQsIA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIEVxdWlsaWJyaXVtIE4yTw0KVGhpcyBjb21wb25lbnQgb2YgdGhlIG1vZGVsIGFsc28gc2VlbWVkIHRvIGJlIGFuIGltcHJvdmVtZW50IG92ZXIgbW9kZWwgMywgd2l0aCBiZXR0ZXIgcmVwcmVzZW50YXRpb24gaW4gdGhlIHRhaWxzIGFzIGluZGljYXRlZCBpbiB0aGUgc2tld25lc3MgX3ZzLl8ga3VydG9zaXMgUFBDLiANCmBgYHtyIHBwY19mdWxsX2NoZWNrc19tb2RfbjJvZXE0LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNC5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KcHBfY2hlY2sobjJvX21vZDQsIA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coRXF1aWxpYnJpdW0gTiJbMl0sIk8pIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJlY2RmX292ZXJsYXkiLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKEVxdWlsaWJyaXVtIE4iWzJdLCJPKSIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1lYW4iLCAic2QiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNCwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q0LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNCwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInNjYXR0ZXJfYXZnIiwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgQml2YXJpYXRlDQpBZ2FpbiwgYW4gaW1wcm92ZW1lbnQgb3ZlciB0aGUgcHJldmlvdXMgbW9kZWwgd2l0aCBhIHRpZ2h0ZXIgZml0IG9mIHRoZSBQUEMgdG8gdGhlIG9ic2VydmVkIGJpdmFyaWF0ZSBkZW5zaXR5Lg0KYGBge3IgcHBjX2J2X2NoZWNrX21vZF9uMm80LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNC5yZGEiKQ0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDIwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvZyhuMm9fb2JzKSwgeSA9IGxvZyhuMm9lcV9vYnMpKSkgKw0KICBnZW9tX2RlbnNpdHlfMmQoYWVzKHggPSBsb2duMm8sIA0KICAgICAgICAgICAgICAgICAgICAgIHkgPSBsb2duMm9lcSwgDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAuZHJhdyksDQogICAgICAgICAgICAgICAgICBiaW5zID0gMTAsDQogICAgICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiLCANCiAgICAgICAgICAgICAgICAgIGFscGhhID0gMC40KSArDQogIGdlb21fZGVuc2l0eV8yZChjb2xvciA9ICJibGFjayIsIGJpbnMgPSAxMCkgKw0KICB4bGltKDEuMjUsIDIuNzUpICsNCiAgeWxpbSgxLjI1LCAyLjc1KSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCiMjIyMgU2F0dXJhdGlvbg0KVGhpcyBjaGVjayBhbHNvIHN1Z2dlc3RlZCBhbiBpbXByb3ZlbWVudCBvdmVyIHRoZSBwcmV2aW91cyBtb2RlbHMsIHdpdGggYmV0dGVyIHRhaWwgYmVoYXZpb3IgYW5kIGxlc3MgYmlhcyBpbiB0aGUgcHJvcG9ydGlvbiB1bmRlci1zYXR1cmF0ZWQgbWVhc3VyZS4NCmBgYHtyIHBwY19zYXRfY2hlY2tfbW9kX24ybzQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gc2F0X3ByZWQsIGdyb3VwID0gLmRyYXcpLCANCiAgICAgICAgICAgICAgIG4gPSAxMDI0LCANCiAgICAgICAgICAgICAgIGFkanVzdCA9IDEsDQogICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fZGVuc2l0eShuID0gMTAyNCwgYWRqdXN0ID0gMikgKw0KICB4bGltKDAsIDUpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q0LCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHVzYXRfcHJlZCA9IGlmZWxzZShleHAobG9nbjJvKSA8IGV4cChsb2duMm9lcSksIDEsIDApKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UocHJvcF9wcmVkID0gc3VtKHVzYXRfcHJlZCkgLyA5ODQpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBwcm9wX3ByZWQpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4wMDEsIGZpbGwgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGRhdGEgPSBkZl9tb2RlbCwgbWFwcGluZyA9IGFlcyh4aW50ZXJjZXB0ID0gc3VtKG4ybyA8IG4yb19lcSkvOTg0KSkgKw0KICB4bGFiKCJQcm9wb3J0aW9uIHVuZGVyc2F0dXJhdGVkIHdhdGVyYm9kaWVzIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCksDQogICAgICAgICBzZF95cmVwID0gc2Qoc2F0X3ByZWQpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKG1lYW5feSA9IG1lYW4oc2F0X3JhdGlvKSwNCiAgICAgICAgIHNkX3kgPSBzZChzYXRfcmF0aW8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2RfeXJlcCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWFuX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBzZF95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBtdXRhdGUobWluX3lyZXAgPSBtaW4oc2F0X3ByZWQpLA0KICAgICAgICAgbWF4X3lyZXAgPSBtYXgoc2F0X3ByZWQpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKG1pbl95ID0gbWluKHNhdF9yYXRpbyksDQogICAgICAgICBtYXhfeSA9IG1heChzYXRfcmF0aW8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWluX3lyZXAsIHkgPSBtYXhfeXJlcCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtaW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IG1heF95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gZXhwKGxvZ24ybykgLyBleHAobG9nbjJvZXEpKSAlPiUNCiAgZ3JvdXBfYnkoLnJvdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSkgJT4lIA0KICBmaWx0ZXIoLmRyYXcgPT0gMSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzYXRfcmF0aW8pKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANCg0KIyMjIyBSLXNxdWFyZQ0KVGhlIEJheWVzaWFuICRSXjIkIGVzdGltYXRlcyBiZWxvdyBpbmRpY2F0ZWQgYW4gaW1wcm92ZW1lbnQgZnJvbSB0aGUgcHJldmlvdXMgbW9kZWxzLg0KYGBge3IgcjJfbW9kX24ybzQsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQpyb3VuZChiYXllc19SMihuMm9fbW9kNCwgcmVzcCA9ICJsb2duMm8iLCBjb3JlcyA9IDEpLCAzKSANCnJvdW5kKGJheWVzX1IyKG4yb19tb2Q0LCByZXNwID0gImxvZ24yb2VxIiwgY29yZXMgPSAxKSwgMykNCmBgYA0KDQojIyMgQ292YXJpYXRlIGVmZmVjdHMNCiMjIyMgTjJPDQpUaGUgY29uZGl0aW9uYWwgZWZmZWN0cyBwbG90cyBmb3IgdGhlIGNvdmFyaWF0ZSBlZmZlY3RzIG9uIE4yTyByZW1haW5lZCBsYXJnZWx5IHVuY2hhbmdlZCBmcm9tIHRoZSBwcmV2aW91cyBtb2RlbC4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfbW9kX24ybzQsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Mn0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQoNCnAxIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24ybyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibm8zX2NhdCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQpwMiA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwgDQogICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgbmNvbCA9IDIpDQoNCnJtKHAxLCBwMikNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgdG9wID0gdGV4dF9ncm9iKGV4cHJlc3Npb24ocGFzdGUoIk4yTzogY292YXJpYXRlIGVmZmVjdHMgb24gIiwgbXUpKSwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpDQpgYGANCg0KQmVsb3cgYXJlIGVzdGltYXRlcyBvZiB0aGUgY29uZGl0aW9uYWwgZWZmZWN0cyBvZiB0aGUgY292YXJpYXRlcyBvbiAkXHNpZ21hJCBmb3IgTjJPLiBUaGVzZSBwbG90cyBzdWdnZXN0ZWQgYSBsYXJnZSBlZmZlY3Qgb2YgTk8zIG9uIHRoZSB2YXJpYW5jZSBvZiBOMk8sIGJ1dCBsaXR0bGUgdG8gbm8gZWZmZWN0IG9mIHN1cmZhY2UgdGVtcGVyYXR1cmUuDQpgYGB7ciBjb25kaXRpb25hbF9lZmZlY3RzX3NpZ21hX24ybzQsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Mn0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q0LnJkYSIpDQoNCnAxIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRwYXIgPSAic2lnbWEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibm8zX2NhdCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQpwMiA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkcGFyID0gInNpZ21hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0pDQoNCnJtKHAxLCBwMikNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgDQogICAgICAgICAgICAgICAgdG9wID0gdGV4dF9ncm9iKGV4cHJlc3Npb24ocGFzdGUoIk4yTzogY292YXJpYXRlIGVmZmVjdHMgb24gIiwgc2lnbWEpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMTQpKQ0KYGBgDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpUaGUgY292YXJpYXRlIGVmZmVjdHMgb24gTjJPIHJlbWFpbmVkIGxhcmdlbHkgdGhlIHNhbWUgYXMgZm9yIHRoZSBwcmV2aW91cyBtb2RlbC4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfbW9kX24yb2VxNCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoImxvZ19lbGV2OnN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24yb2VxIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJzdXJmdGVtcDpsb2dfZWxldiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLA0KICAgICAgICAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSkNCg0Kcm0ocDEsIHAyKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiRXF1aWxpYnJpdW0gTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBtdSkpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkNCmBgYA0KDQpUaGUgY292YXJpYXRlIGVmZmVjdHMgb24gJFxzaWdtYSQgZm9yIE4yTy1lcSBzdWdnZXN0ZWQgYW4gbmVnYXRpdmUgZWZmZWN0IG9mIHN1cmZhY2UgdGVtcGVyYXR1cmUgYW5kIGxpdHRlIHRvIG5vIGVmZmVjdCBvZiBlbGV2YXRpb24uDQpgYGB7ciBjb25kaXRpb25hbF9lZmZlY3RzX3NpZ21hX24yb2VxNCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDQucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkcGFyID0gInNpZ21hIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaWdtYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJsb2dfZWxldiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLA0KICAgICAgICAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSkNCg0Kcm0ocDEsIHAyKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiRXF1aWxpYnJpdW0gTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBzaWdtYSkpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkNCmBgYA0KDQojIyBNb2RlbCA1DQpJbiB0aGUgbmV4dCBtb2RlbCwgbW9yZSBjb21wbGV4aXR5IGlzIGFkZGVkIHRvIHRoZSBOMk8gY29tcG9uZW50IGJ5IGluY2x1ZGluZyBhIGNvdmFyaWF0ZSBmb3IgbGFrZSBzdXJmYWNlIGFyZWEgKGxvZyBzY2FsZSkgYXMgd2VsbCBhcyBpbnRlcmFjdGlvbnMgYmV0d2VlbiBOTzMgYW5kIGxvZyhhcmVhKSBhbmQgc3VyZmFjZSB0ZW1wZXJhdHVyZS4gDQpgYGB7ciBuMm9fbW9kX212XzUsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQoNCmJmX24ybyA8LSBiZihsb2cobjJvKSB+IG1vKG5vM19jYXQpICsNCiAgICAgICAgICAgICAgIGxvZ19hcmVhICsNCiAgICAgICAgICAgICAgIHN1cmZ0ZW1wICsgDQogICAgICAgICAgICAgICBtbyhubzNfY2F0KTpsb2dfYXJlYSArDQogICAgICAgICAgICAgICBtbyhubzNfY2F0KTpzdXJmdGVtcCArDQogICAgICAgICAgICAgICAobW8obm8zX2NhdCkgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgIChtbyhubzNfY2F0KSB8IGIgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgc2lnbWEgfiBsb2dfYXJlYSArDQogICAgICAgICAgICAgICBtbyhubzNfY2F0KSArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLCANCiAgICAgICAgICAgICBmYW1pbHkgPSBnYXVzc2lhbigpKQ0KDQpiZl9uMm9lcSA8LSBiZihsb2cobjJvX2VxKSB+IHN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgICAgbG9nX2VsZXYgKw0KICAgICAgICAgICAgICAgICBzdXJmdGVtcDpsb2dfZWxldiArDQogICAgICAgICAgICAgICAgICgxIHwgYSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAgICgxIHwgYiB8IFdTQTk6c3RhdGUpICsNCiAgICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgc2lnbWEgfiBzdXJmdGVtcCArDQogICAgICAgICAgICAgICBsb2dfZWxldiArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIGZhbWlseSA9IGdhdXNzaWFuKCkpDQoNCnByaW9ycyA8LSBjKA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIHJlc3AgPSAibG9nbjJvIiksDQogIHByaW9yKG5vcm1hbCgtMSwgMiksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24ybyIpLA0KICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gImIiLCBkcGFyID0gInNpZ21hIiwgcmVzcCA9ICJsb2duMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgZHBhciA9ICJzaWdtYSIsIHJlc3AgPSAibG9nbjJvIiksDQogIA0KICBwcmlvcihub3JtYWwoMiwgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIHJlc3AgPSAibG9nbjJvZXEiKSwgDQogIHByaW9yKG5vcm1hbCgtMSwgMiksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIGRwYXIgPSAic2lnbWEiLCByZXNwID0gImxvZ24yb2VxIiksDQogIA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gInJlc2NvciIpLA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gImNvciIpDQogICkNCg0KbjJvX21vZDUgPC0gYnJtKGJmX24ybyArIA0KICAgICAgICAgICAgICAgICAgYmZfbjJvZXEgKw0KICAgICAgICAgICAgICAgICAgc2V0X3Jlc2NvcihyZXNjb3IgPSBUUlVFKSwNCiAgICAgICAgICAgICAgICBkYXRhID0gZGZfbW9kZWwsIA0KICAgICAgICAgICAgICAgIHByaW9yID0gcHJpb3JzLA0KICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTc1LCBtYXhfdHJlZWRlcHRoID0gMTIpLA0KICAjc2FtcGxlX3ByaW9yID0gIm9ubHkiLA0KICBzYXZlX3BhcnMgPSBzYXZlX3BhcnMoYWxsID0gVFJVRSksDQogIHNlZWQgPSA1NDc0MSwNCiAgY2hhaW5zPTQsIA0KICBpdGVyPTUwMDAsIA0KICBjb3Jlcz00KQ0KDQpzYXZlKG4yb19tb2Q1LCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQpgYGANCg0KIyMjIFN1bW1hcml6ZSBmaXQNCkJlbG93IGlzIGEgc3VtbWFyeSBvZiB0aGUgZml0dGVkIHBhcmFtZXRlcnMgYWxvbmcgd2l0aCBNQ01DIGNvbnZlcmdlbmNlIGRpYWdub3N0aWNzLg0KYGBge3IgcHJpbnRfbW9kNSwgZWNobz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQoNCnByaW50KG4yb19tb2Q1LCBwcmlvciA9IFQsIGRpZ2l0cyA9IDMpDQpgYGANCg0KIyMjIE1vZGVsIGNoZWNrcw0KQWdhaW4sIHRoZSBzYW1lIFBQQ3MgYXMgYWJvdmUgd2VyZSBwZXJmb3JtZWQgZm9yIHRoaXMgbW9kZWwuDQojIyMjIE4yTyBQUEMNClRoaXMgUFBDIGZvciBOMk8gbG9va2VkIHNpbWlsYXIgdG8gdGhlIHByZXZpb3VzIG1vZGVsLg0KYGBge3IgcHBjX2Z1bGxfY2hlY2tzX21vZF9uMm81LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNS5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJkZW5zX292ZXJsYXkiLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q1LCANCiAgICAgICAgIG5kcmF3cyA9IDIwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiY3VtdWxhdGl2ZSBkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q1LCANCiAgICAgICAgIG5kcmF3cyA9IDEwMDAsDQogICAgICAgICByZXNwID0gImxvZ24ybyIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtZWFuIiwgInNkIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoIm1pbiIsICJtYXgiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm8iLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIEVxdWlsaWJyaXVtIE4yTw0KQWdhaW4sIHRoZSBQUENzIGZvciB0aGlzIG1vZGVsIHdlcmUgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgbW9kZWwsIHdoaWNoIHdhcyB1bnN1cnByaXNpbmcgZ2l2ZW4gdGhhdCBpdCB3YXMgdGhlIHNhbWUgbW9kZWwgZm9yIE4yTy1lcS4NCmBgYHtyIHBwY19mdWxsX2NoZWNrc19tb2RfbjJvZXE1LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNS5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coRXF1aWxpYnJpdW0gTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMjAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gImVjZGZfb3ZlcmxheSIsDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJsb2coRXF1aWxpYnJpdW0gTiJbMl0sIk8pIGNvbmNlbnRyYXRpb24iKSkpICsgDQogIHlsYWIoImN1bXVsYXRpdmUgZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtZWFuIiwgInNkIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygia3VydG9zaXMiLCAic2tld25lc3MiKSwgDQogICAgICAgICBjb3JlcyA9IDEpICsgDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpwcF9jaGVjayhuMm9fbW9kNSwgDQogICAgICAgICBuZHJhd3MgPSAxMDAwLA0KICAgICAgICAgcmVzcCA9ICJsb2duMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtaW4iLCAibWF4IiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDUsIA0KICAgICAgICAgbmRyYXdzID0gMTAwMCwNCiAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIEJpdmFyaWF0ZQ0KVGhpcyBQUEMgd2FzIGFsc28gc2ltaWxhciB0byB0aGUgcHJldmlvdXMgbW9kZWwuDQpgYGB7ciBwcGNfYnZfY2hlY2tfbW9kX24ybzUsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gMjApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9nKG4yb19vYnMpLCB5ID0gbG9nKG4yb2VxX29icykpKSArDQogIGdlb21fZGVuc2l0eV8yZChhZXMoeCA9IGxvZ24ybywgDQogICAgICAgICAgICAgICAgICAgICAgeSA9IGxvZ24yb2VxLCANCiAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IC5kcmF3KSwNCiAgICAgICAgICAgICAgICAgIGJpbnMgPSAxMCwNCiAgICAgICAgICAgICAgICAgIGNvbG9yID0gImxpZ2h0Ymx1ZSIsIA0KICAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjQpICsNCiAgZ2VvbV9kZW5zaXR5XzJkKGNvbG9yID0gImJsYWNrIiwgYmlucyA9IDEwKSArDQogIHhsaW0oMS4yNSwgMi43NSkgKw0KICB5bGltKDEuMjUsIDIuNzUpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KIyMjIyBTYXR1cmF0aW9uDQpUaGlzIGNoZWNrIHdhcyBhbHNvIHNpbWlsYXIgdG8gdGhlIHByZXZvaXVzIG1vZGVsLCB3aXRoIHBlcmhhcHMgc2xpZ2h0bHkgbGVzcyBiaWFzIGluIHRoZSBwcm9wb3J0aW9uIHVuc2F0dXJhdGVkIGVzdGltYXRlcy4gVGhlcmUgaXMgYWxzbyBhIHBvdGVudGlhbGx5IGNvbmNlcm5pbmcgZXh0cmVtZSBwcmVkaWN0aW9uIGluIHRoZSBvYnNlcnZlZCBfdnNfIHByZWRpY3RlZCBQUEMuDQpgYGB7ciBwcGNfc2F0X2NoZWNrX21vZF9uMm81LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNS5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBleHAobG9nbjJvKSAvIGV4cChsb2duMm9lcSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzYXRfcmF0aW8pKSArDQogIGdlb21fZGVuc2l0eShhZXMoeCA9IHNhdF9wcmVkLCBncm91cCA9IC5kcmF3KSwgDQogICAgICAgICAgICAgICBuID0gMTAyNCwgDQogICAgICAgICAgICAgICBhZGp1c3QgPSAxLA0KICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX2RlbnNpdHkobiA9IDEwMjQsIGFkanVzdCA9IDIpICsNCiAgeGxpbSgwLCA1KSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZSh1c2F0X3ByZWQgPSBpZmVsc2UoZXhwKGxvZ24ybykgPCBleHAobG9nbjJvZXEpLCAxLCAwKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKHByb3BfcHJlZCA9IHN1bSh1c2F0X3ByZWQpIC8gOTg0KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHJvcF9wcmVkKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDAxLCBmaWxsID0gImxpZ2h0Ymx1ZSIpICsNCiAgZ2VvbV92bGluZShkYXRhID0gZGZfbW9kZWwsIG1hcHBpbmcgPSBhZXMoeGludGVyY2VwdCA9IHN1bShuMm8gPCBuMm9fZXEpLzk4NCkpICsNCiAgeGxhYigiUHJvcG9ydGlvbiB1bmRlcnNhdHVyYXRlZCB3YXRlcmJvZGllcyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpLA0KICAgICAgICAgc2RfeXJlcCA9IHNkKHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtZWFuX3kgPSBtZWFuKHNhdF9yYXRpbyksDQogICAgICAgICBzZF95ID0gc2Qoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNkX3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWVhbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gc2RfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1pbl95cmVwID0gbWluKHNhdF9wcmVkKSwNCiAgICAgICAgIG1heF95cmVwID0gbWF4KHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtaW5feSA9IG1pbihzYXRfcmF0aW8pLA0KICAgICAgICAgbWF4X3kgPSBtYXgoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1pbl95cmVwLCB5ID0gbWF4X3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWluX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBtYXhfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IGV4cChsb2duMm8pIC8gZXhwKGxvZ24yb2VxKSkgJT4lDQogIGdyb3VwX2J5KC5yb3cpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCkpICU+JSANCiAgZmlsdGVyKC5kcmF3ID09IDEpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2F0X3JhdGlvKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosIG5jb2wgPSAyKQ0KYGBgDQoNCiMjIyMgUi1zcXVhcmUNCmBgYHtyIHIyX21vZF9uMm81LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTR9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNS5yZGEiKQ0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDUsIHJlc3AgPSAibG9nbjJvIiwgY29yZXMgPSAxKSwgMykgDQpyb3VuZChiYXllc19SMihuMm9fbW9kNSwgcmVzcCA9ICJsb2duMm9lcSIsIGNvcmVzID0gMSksIDMpDQpgYGANCg0KIyMjIENvdmFyaWF0ZSBlZmZlY3RzDQojIyMjIE4yTw0KVGhlIGNvbmRpdGlvbmFsIGVmZmVjdHMgcGxvdCBmb3IgdGhlIGNvdmFyaWF0ZSBlZmZlY3RzIE4yTyBzdWdnZXN0ZWQgYSBzaW1pbGFyIGVmZmVjdCBvZiBOTzMsIGJ1dCBpbnRlcmVzdGluZyBpbnRlcmFjdGlvbnMgYmV0d2VlbiBOTzMgYW5kIGxha2UgYXJlYSBhbmQgTk8zIGFuZCBzdXJmYWNlIHRlbXBlcmF0dXJlLiBGb3IgbGFrZSBhcmVhLCB0aGUgZWZmZWN0IHdhcyBlc3RpbWF0ZWQgdG8gYmUgbGFyZ2VyIGFuZCBtb3JlIG5lZ2F0aXZlIGF0IHRoZSBoaWdoZXN0IGxldmVscyBvZiBOTzM7IGFuZCBzbGlnaHRseSBuZWdhdGl2ZSBhdCB0aGUgbG93ZXN0IGxldmVsIG9mIE5PMy4gRm9yIHN1cmZhY2UgdGVtcGVyYXR1cmUsIHRoZSBlZmZlY3Qgd2FzIGVzdGltYXRlZCB0byBiZSBsYXJnZXN0IGFuZCBwb3NpdGl2ZSBhdCB0aGUgaGlnaGVzdCBsZXZlbCBvZiBOTzM7IGFuZCBuZWdhdGl2ZSBhdCB0aGUgbG93ZXN0IGxldmVsIG9mIE5PMy4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfbW9kX24ybzUsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQoNCnAxIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24ybyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibm8zX2NhdCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24ybyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibG9nX2FyZWE6bm8zX2NhdCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQpwMyA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q1LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJsb2duMm8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wOm5vM19jYXQiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLCANCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDMsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIsIHAzKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBtdSkpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkNCmBgYA0KDQpUaGUgZXN0aW1hdGVkIGNvdmFyaWF0ZSBlZmZlY3RzIG9uICRcc2lnbWEkIHN1Z2dlc3RlZCBhIG5lZ2F0aXZlIHJlbGF0aW9uc2hpcCB3aXRoIGxvZyhhcmVhKSBhbmQgYSBwb3NpdGl2ZSByZWxhdGlvbnNoaXAsIGFnYWluLCB3aXRoIE5PMy4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfc2lnbWFfbjJvNSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDUucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaWdtYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJsb2dfYXJlYSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaWdtYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJubzNfY2F0IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0pDQoNCnJtKHAxLCBwMikNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgDQogICAgICAgICAgICAgICAgdG9wID0gdGV4dF9ncm9iKGV4cHJlc3Npb24ocGFzdGUoIk4yTzogY292YXJpYXRlIGVmZmVjdHMgb24gIiwgc2lnbWEpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMTQpKQ0KYGBgDQoNCiMjIyMgRXF1aWxpYnJpdW0gTjJPDQpUaGUgZXN0aW1hdGVkIGNvdmFyaWF0ZSBlZmZlY3Qgb24gTjJPIHJlbWFpbmVkIGxhcmdlbHkgdGhlIHNhbWUgYXMgZXN0aW1hdGVkIGluIHRoZSBwcmV2aW91cyBtb2RlbC4NCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfbW9kX24yb2VxNSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDUucmRhIikNCg0KcDEgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoInN1cmZ0ZW1wOmxvZ19lbGV2IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcDIgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibG9nbjJvZXEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoImxvZ19lbGV2OnN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwNCiAgICAgICAgICAgICAgICAgcGxvdChwMiwgcGxvdCA9IEYpW1sxXV0pDQoNCnJtKHAxLCBwMikNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgdG9wID0gdGV4dF9ncm9iKGV4cHJlc3Npb24ocGFzdGUoIkVxdWlsaWJyaXVtIE4yTzogY292YXJpYXRlIGVmZmVjdHMgb24gIiwgbXUpKSwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpDQpgYGANCg0KYGBge3IgY29uZGl0aW9uYWxfZWZmZWN0c19zaWdtYV9uMm9lcTUsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Mn0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q1LnJkYSIpDQoNCnAxIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaWdtYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJzdXJmdGVtcCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gImxvZ24yb2VxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBhciA9ICJzaWdtYSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJsb2dfZWxldiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIHRvcCA9IHRleHRfZ3JvYihleHByZXNzaW9uKHBhc3RlKCJFcXVpbGlicml1bSBOMk86IGNvdmFyaWF0ZSBlZmZlY3RzIG9uICIsIHNpZ21hKSksIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpKQ0KYGBgDQoNCiMjIEEgRmluYWwgTW9kZWwNCkFzIGRlbW9uc3RyYXRlZCBhYm92ZSwgbW9kZWxzIGV4Y2x1ZGluZyB0aGUgTk8zIGNvdmFyaWF0ZSBjb25zaXN0ZW50bHkgcmVzdWx0ZWQgaW4gcG9vcmVyIGZpdHMgdG8gdG8gdGhlIG9ic2VydmVkIGRpc3NvbHZlZCBOMk8gZGF0YS4gSW5jbHVkaW5nIHN1cmZhY2UgdGVtcGVyYXR1cmUgYW5kIGVsZXZhdGlvbiBpbiB0aGUgZXF1aWxpYnJpdW0gTjJPIHBhcnQgb2YgdGhlIG1vZGVsIHJlc3VsdGVkIGluIHN1YnN0YW50aWFsbHkgaW1wcm92ZWQgcmVwbGljYXRpb24gb2Yga2V5IGFzcGVjdHMgb2YgdGhlIG9ic2VydmVkIGRhdGEuIExpa2V3aXNlLCBhZGRlZCBmbGV4aWJpbGl0eSBpbiB0aGUgZGlzdHJpYnV0aW9uYWwgdGVybXMgZm9yIGJvdGggZGlzc29sdmVkIGFuZCBlcXVpbGlicml1bSBOMk8gbGVkIHRvIGltcHJvdmVtZW50cy4gDQoNClRvIG1ha2UgaW5mZXJlbmNlcyBmcm9tIHRoaXMgbW9kZWwgZm9yIE4yTyBpbiB0aGUgcG9wdWxhdGlvbiBvZiBpbnRlcmVzdCwgaG93ZXZlciwgdGhlIGluY2x1ZGVkIGNvdmFyaWF0ZXMgbmVlZGVkIHRvIGJlICgxKSBmdWxseSBvYnNlcnZlZCBhY3Jvc3MgdGhhdCBwb3B1bGF0aW9uIG9yICgyKSB0aGVpciBtaXNzaW5nbmVzcyBuZWVkZWQgdG8gYmUgbW9kZWxlZC4gRm9yIHRoZSBsYWtlIGFyZWEgYW5kIGVsZXZhdGlvbiBjb3ZhcmlhdGVzLCBkYXRhIF93YXNfIGF2YWlsYWJsZSBmb3IgYWxsIGxha2VzIGZyb20gcHJldmlvdXNseSBjb21waWxlZCBnZW9zcGF0aWFsIGRhdGFiYXNlcy4gSG93ZXZlciwgbmVpdGhlciBzdXJmYWNlIHRlbXBlcmF0dXJlIG9yIE5PMyB3ZXJlIG9ic2VydmVkIGZvciBsYWtlcyBvdXRzaWRlIG9mIHRoZSBzYW1wbGUuIFRoZXkgd2VyZSBwYXJ0aWFsbHkgb2JzZXJ2ZWQgd2l0aCByZXNwZWN0IHRvIHRoZSB0YXJnZXQgcG9wdWxhdGlvbi4gVGhlaXIgbWlzc2luZ25lc3MgbmVlZGVkIHRvIGJlIGFjY291bnRlZCBmb3IgaW4gYSBtb2RlbC4gVGhlcmVmb3JlLCBhIG1vcmUgY29tcGxleCBtb2RlbCB3YXMgY29uc3RydWN0ZWQgYmVsb3cgdGhhdCBpbmNsdWRlZCBzdXJmYWNlIHRlbXBlcmF0dXJlIGFuZCBOTzMgYXMgYWRkaXRpb25hbCByZXNwb25zZXMgY29uZGl0aW9uZWQgb24gdGhlIHN1cnZleSBkZXNpZ24gdmFyaWFibGVzIGFuZCBmdWxseSBvYnNlcnZlZCBjb3ZhcmlhdGVzLiBUaGlzIGFwcHJvYWNoIHRvIGluZmVyZW5jZSBmb3IgTjJPIHdhcyBzaW1pbGFyIHRvIGEgQmF5ZXNpYW4gc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbCBbQE1lcmtsZV9ldGFsXzIwMjE7IEBNZXJrbGVfUm9zc2VlbF8yMDE4XS4gVGhlIG1haW4gZGV0YWlscyBvZiB0aGUgbG9naWNhbCBkZXBlbmRlbmNlIHN0cnVjdHVyZSBjb3VsZCBiZSBjaGFyYWN0ZXJpemVkIGFzOg0KDQokJFxiZWdpbnthbGlnbn0gDQpcY29sb3J7IzFGNDQ5Q317XGJvbGRzeW1ib2x7Tl8yT197ZGlzc319fSAmPVxzaW0gU3VydmV5ICsgQXJlYSArIFxjb2xvcnsjRjA1MDM5fXtcYm9sZHN5bWJvbHtOT18zfX0gKyBcY29sb3J7I0VFQkFCNH17XGJvbGRzeW1ib2x7VGVtcH19IFxcIA0KXGNvbG9yeyNBOEI2Q0N9e1xib2xkc3ltYm9se05fMk9fe2VxdWlsfX19ICY9XHNpbSBTdXJ2ZXkgKyBFbGV2ICArIFxjb2xvcnsjRUVCQUI0fXtcYm9sZHN5bWJvbHtUZW1wfX1cXA0KXGNvbG9yeyNGMDUwMzl9e1xib2xkc3ltYm9se05PXzN9fSAmPVxzaW0gU3VydmV5ICsgQXJlYSArIFxjb2xvcnsjRUVCQUI0fXtcYm9sZHN5bWJvbHtUZW1wfX0gXFwgDQpcY29sb3J7I0VFQkFCNH17XGJvbGRzeW1ib2x7VGVtcH19ICY9XHNpbSBTdXJ2ZXkgKyBMYXQgKyBFbGV2ICsgRGF5DQpcZW5ke2FsaWdufSQkDQoNClZhcmlhYmxlcyBpbiBjb2xvciB0ZXh0IGFib3ZlIHdlcmUgdHJlYXRlZCBhcyBwYXJ0aWFsbHkgb2JzZXJ2ZWQgd2l0aCByZXNwZWN0IHRvIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0IChpLmUuLCBvYnNlcnZlZCBvbmx5IGluIHRoZSBzYW1wbGUpLCB3aGVyZWFzIHZhcmlhYmxlcyBpbiBibGFjayB0ZXh0IHdlcmUgY29uc2lkZXJlZCBmdWxseSBvYnNlcnZlZC4gVGhlIHBhcnRpYWxseSBvYnNlcnZlZCB2YXJpYWJsZXMsIGJlaW5nIGRpc3NvbHZlZCBhbmQgZXF1aWxpYnJpdW0gTjJPLCBOTzMsIGFuZCBzdXJmYWNlIHRlbXBlcmF0dXJlLCB3ZXJlIGVhY2ggbW9kZWxlZCBjb25kaXRpb25hbCBvbiB0aGUgc3VydmV5IGRlc2lnbiB2YXJpYWJsZXMgYW5kIG90aGVyIHBhcnRpYWxseSBhbmQvb3IgZnVsbHkgb2JzZXJ2ZWQgY292YXJpYXRlcy4gVGhpcyBzdHJ1Y3R1cmFsIGVxdWF0aW9uIGFwcHJvYWNoIHJlcXVpcmVzIGEgbW9yZSBjb21wbGV4IHNldCBvZiBwb3N0LXByb2Nlc3Npbmcgc3RlcHMgY29tcGFyZWQgdG8gYSB0eXBpY2FsIE1SUCBhbmFseXNpcy4gSW4gb3JkZXIgdG8gcHJvcGFnYXRlIGVzdGltYXRlcyBhbmQgdW5jZXJ0YWludHkgdGhyb3VnaCB0aGUgZGVwZW5kZW5jeSBzdHJ1Y3R1cmUgYW5kIG1ha2UgaW5mZXJlbmNlcywgdGhlIGZpdHRlZCBtb2RlbCB3YXMgdXNlZCB0byBmaXJzdCBwcmVkaWN0IHN1cmZhY2UgdGVtcGVyYXR1cmUgaW4gdGhlIHRhcmdldCBwb3B1bGF0aW9uLCBzaW5jZSBpdCBkZXBlbmRlZCBvbmx5IG9uIHRoZSBmdWxseSBvYnNlcnZlZCBjb3ZhcmlhdGVzLiBUaGF0IHByZWRpY3RpdmUgZGlzdHJpYnV0aW9uIHdhcyB0aGVuIHVzZWQgYWxvbmdzaWRlIHRoZSByZWxldmFudCBmdWxseSBvYnNlcnZlZCBjb3ZhcmlhdGVzIHRvIHByZWRpY3QgTk8zIGluIHRoZSB0YXJnZXQgcG9wdWxhdGlvbi4gRmluYWxseSwgdGhlIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9ucyBmb3IgdGVybXBlcmF0dXJlIGFuZCBOTzMgd2VyZSB1c2VkIHRvIHByZWRpY3QgdGhlIE4yTyByZXNwb25zZXMuIFRoZXNlIHN0ZXBzIHdlcmUgY2FycmllZCBvdXQgaW4gdGhlICJQcmVkaWN0IHRvIHBvcHVsYXRpb24iIHNlY3Rpb24gdG8gZm9sbG93Lg0KDQpJbiB0aGUgZmluYWwgbW9kZWwgYmVsb3csIHRoZSBzdWJtb2RlbCBmb3Igc3VyZmFjZSB0ZW1wZXJhdHVyZSBhc3N1bWVkIGEgR2FtbWEgZGlzdHJpYnV0ZWQgZXJyb3IgZGlzdHJpYnV0aW9uIGFuZCB0aGUgbGluZWFyIHByZWRpY3RvciBpbmNsdWRlZCB0aGUgc3VydmV5IGRlc2lnbiB2YXJpYWJsZXMsIGxhdGl0dWRlLCBlbGV2YXRpb24sIGFuZCBqdWxpYW4gZGF0ZS4gVGhlIHNoYXBlIHBhcmFtZXRlciB3YXMgYWxzbyBtb2RlbGVkIGFzIGEgZnVuY3Rpb24gb2YgbGF0aXR1ZGUgdG8gYWRkcmVzcyBpbmNyZWFzaW5nIHJlc3BvbnNlIHZhcmlhbmNlIGFsb25nIHRoZSBsYXRpdHVkaW5hbCBncmFkaWVudC4gVGhlIE5PMyBzdWJtb2RlbCB3YXMgYSBjdW11bGF0aXZlIGxvZ2l0IGZvcm11bGF0aW9uIGFuZCB0aGUgbGluZWFyIHByZWRpY3RvciBpbmNsdWRlZCBhbGwgb2YgdGhlIHN1cnZleSBmYWN0b3JzIGFzIHdlbGwgYXMgc3VyZmFjZSB0ZW1wZXJhdHVyZSBhbmQgbGFrZSBhcmVhLiANCg0KVGhlIE4yTyBhbmQgTjJPLWVxIHJlc3BvbnNlcyB3ZXJlIGVhY2ggbW9kZWxlZCB3aXRoIEdhbW1hIGRpc3RyaWJ1dGVkIGVycm9ycywgYnV0IHdpdGggdGhlIHNhbWUgY292YXJpYXRlIHN0cnVjdHVyZSBhcyBpbiBtb2RlbCA1LiBUaGUgc2FtZSBzdHJ1Y3R1cmUgd2FzIGFsc28gZW1wbG95ZWQgZm9yIHRoZSBzaGFwZSB0ZXJtcyBpbiB0aGVzZSByZXNwb25zZXMsIGNvcnJlc3BvbmRpbmcgdG8gdGhlICRcc2lnbWEkIHRlcm1zIGluIHRoZSBwcmV2aW91cyBtb2RlbC4gVGhvdWdoIG5vdCBzaG93biBpbiB0aGlzIGRvY3VtZW50LCB0aGUgR2FtbWEgZXJyb3Igc3RydWN0dXJlIGFwcGVhcmVkIHRvIHJlc3VsdCBpbiBzbGlnaHRseSBiZXR0ZXIgcGVyZm9ybWFuY2UgaW4gdGhlIHByZWRpY3RpdmUgY2hlY2tzIGNvbXBhcmVkIHRvIHRoZSBHYXVzc2lhbiBlcnJvcnMgaW4gcHJldmlvdXMgbW9kZWxzLiBUaGlzIHdhcyBwcmltYXJpbHkgYXBwYXJlbnQgaW4gdGhlIHNhdHVyYXRpb24gcmF0aW8gY2hlY2tzLCB3aGljaCBtYXkgaGF2ZSBiZWVuIG1vcmUgc2Vuc2l0aXZlIHRvIG1vZGVsIHBlcmZvcm1hbmNlIGluIHRoZSB0YWlscyBvZiB0aGUgTjJPIHJlc3BvbnNlcy4gT3RoZXJzIGhhdmUgYWxzbyBpbmRpY2F0ZWQgdGhhdCB0aGUgR2FtbWEgZXJyb3IgZGlzdHJpYnV0aW9uIGNhbiB3b3JrIHdlbGwgZm9yIGRpc3NvbHZlZCBOMk8gZGF0YSBbQFdlYmJfZXRhbF8yMDE5XS4NCg0KTm90ZSB0aGF0IHRoZXJlIHdhcyBubyByZXNpZHVhbCBjb3JyZWxhdGlvbiB0ZXJtIGZvciB0aGlzIG1vZGVsLCBzaW5jZSB0aGUgcmVzaWR1YWxzIGFyZSB1bmRlZmluZWQgZm9yIHRoZSBHYW1tYSBhbmQgY3VtdWxhdGl2ZSBsb2dpdCBtb2RlbHMuIERyb3BwaW5nIHRoZSBvYnNlcnZhdGlvbi1sZXZlbCByZXNpZHVhbCBjb3JyZWxhdGlvbiB0ZXJtIHdhcyBkZWVtZWQgYSByZWFzb25hYmxlIGNvbXByb21pc2UgdGhhdCBlbmFibGVkIG1vZGVsaW5nIHRoZSBtaXNzaW5nbmVzcyBvZiBOTzMsIGluIHBhcnRpY3VsYXIuIE5ldmVydGhlbGVzcywgdGhlIHJhbmRvbSBpbnRlcmNlcHRzIGFnYWluIGFsbG93ZWQgZm9yIHBvdGVudGlhbCBjb3JyZWxhdGlvbnMgYmV0d2VlbiByZXNwb25zZXMgYXQgdGhlIGdyb3VwIGxldmVscy4gDQoNCmBgYHtyIG4yb19tb2RfbXZfNiwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCg0KYmZfbjJvIDwtIGJmKG4ybyB+IG1vKG5vM19jYXQpICsNCiAgICAgICAgICAgICAgIGxvZ19hcmVhICsNCiAgICAgICAgICAgICAgIHN1cmZ0ZW1wICsgDQogICAgICAgICAgICAgICBtbyhubzNfY2F0KTpsb2dfYXJlYSArDQogICAgICAgICAgICAgICBtbyhubzNfY2F0KTpzdXJmdGVtcCArDQogICAgICAgICAgICAgICAobW8obm8zX2NhdCkgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgIChtbyhubzNfY2F0KSB8IGIgfCBXU0E5OnN0YXRlKSArIA0KICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgc2hhcGUgfiBsb2dfYXJlYSArDQogICAgICAgICAgICAgICBtbyhubzNfY2F0KSArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIGZhbWlseSA9IEdhbW1hKGxpbmsgPSAibG9nIikpDQoNCmJmX24yb2VxIDwtIGJmKG4yb19lcSB+IHN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgICAgbG9nX2VsZXYgKw0KICAgICAgICAgICAgICAgICBzdXJmdGVtcDpsb2dfZWxldiArDQogICAgICAgICAgICAgICAgICgxIHwgYSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAgICgxIHwgYiB8IFdTQTk6c3RhdGUpICsNCiAgICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgc2hhcGUgfiBzdXJmdGVtcCArDQogICAgICAgICAgICAgICBsb2dfZWxldiArDQogICAgICAgICAgICAgICAoMSB8IFdTQTkpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGUpICsgDQogICAgICAgICAgICAgICAoMSB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIGZhbWlseSA9IEdhbW1hKGxpbmsgPSAibG9nIikpDQoNCmJmX3RlbXAgPC0gYmYoc3VyZnRlbXAgfiBsYXQgKw0KICAgICAgICAgICAgICAgIHMobG9nX2VsZXYpICsNCiAgICAgICAgICAgICAgICBzKGpkYXRlKSArDQogICAgICAgICAgICAgICAgKDEgfCBhIHwgV1NBOSkgKyANCiAgICAgICAgICAgICAgICAoMSB8IGIgfCBXU0E5OnN0YXRlKSArDQogICAgICAgICAgICAgICAgKDEgfCBjIHwgV1NBOTpzdGF0ZTpzaXplX2NhdCksDQogICAgICAgICAgICAgIHNoYXBlIH4gbGF0LA0KICAgICAgICAgICAgICBmYW1pbHkgPSBHYW1tYShsaW5rID0gImxvZyIpKQ0KDQpiZl9ubzMgPC0gYmYobm8zX2NhdCB+IHN1cmZ0ZW1wICsNCiAgICAgICAgICAgICAgIGxvZ19hcmVhICsNCiAgICAgICAgICAgICAgICgxIHwgYSB8IFdTQTkpICsNCiAgICAgICAgICAgICAgICgxIHwgYiB8IFdTQTk6c3RhdGUpICsNCiAgICAgICAgICAgICAgICgxIHwgYyB8IFdTQTk6c3RhdGU6c2l6ZV9jYXQpLA0KICAgICAgICAgICAgIGZhbWlseSA9IGN1bXVsYXRpdmUobGluayA9ICJsb2dpdCIsIHRocmVzaG9sZD0iZmxleGlibGUiKSkNCg0KcHJpb3JzIDwtIGMoDQogIHByaW9yKG5vcm1hbCgyLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiwgcmVzcCA9ICJuMm8iKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgcmVzcCA9ICJuMm8iKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJuMm8iKSwNCiAgcHJpb3Iobm9ybWFsKDUsIDQpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCBkcGFyID0gInNoYXBlIiwgcmVzcCA9ICJuMm8iKSwNCiAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9ICJiIiwgZHBhciA9ICJzaGFwZSIsIHJlc3AgPSAibjJvIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIGRwYXIgPSAic2hhcGUiLCByZXNwID0gIm4ybyIpLA0KICANCiAgcHJpb3Iobm9ybWFsKDIsIDEpLCBjbGFzcyA9ICJJbnRlcmNlcHQiLCByZXNwID0gIm4yb2VxIiksIA0KICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gImIiLCByZXNwID0gIm4yb2VxIiksICANCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJuMm9lcSIpLA0KICBwcmlvcihub3JtYWwoNSwgNCksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2hhcGUiLCByZXNwID0gIm4yb2VxIiksDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIGRwYXIgPSAic2hhcGUiLCByZXNwID0gIm4yb2VxIiksDQogIHByaW9yKGV4cG9uZW50aWFsKDIpLCBjbGFzcyA9ICJzZCIsIGRwYXIgPSAic2hhcGUiLCByZXNwID0gIm4yb2VxIiksDQogIA0KICBwcmlvcihub3JtYWwoMywgMSksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAic3VyZnRlbXAiKSwgDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIHJlc3AgPSAic3VyZnRlbXAiKSwgDQogIHByaW9yKGV4cG9uZW50aWFsKDAuNSksIGNsYXNzID0gInNkcyIsIHJlc3AgPSAic3VyZnRlbXAiKSwNCiAgcHJpb3IoZXhwb25lbnRpYWwoMiksIGNsYXNzID0gInNkIiwgcmVzcCA9ICJzdXJmdGVtcCIpLA0KICBwcmlvcihub3JtYWwoNSwgNCksIGNsYXNzID0gIkludGVyY2VwdCIsIGRwYXIgPSAic2hhcGUiLCByZXNwID0gInN1cmZ0ZW1wIiksDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIGRwYXIgPSAic2hhcGUiLCByZXNwID0gInN1cmZ0ZW1wIiksDQogIA0KICBwcmlvcihub3JtYWwoMCwgMyksIGNsYXNzID0gIkludGVyY2VwdCIsIHJlc3AgPSAibm8zY2F0IiksDQogIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiYiIsIHJlc3AgPSAibm8zY2F0IiksDQogIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9ICJzZCIsIHJlc3AgPSAibm8zY2F0IiksDQogIA0KICBwcmlvcihsa2ooMiksIGNsYXNzID0gImNvciIpDQogICkNCg0KbjJvX21vZDYgPC0gYnJtKGJmX24ybyArIA0KICAgICAgICAgICAgICAgICAgYmZfbjJvZXEgKyANCiAgICAgICAgICAgICAgICAgIGJmX3RlbXAgKyANCiAgICAgICAgICAgICAgICAgIGJmX25vMyArIA0KICAgICAgICAgICAgICAgICAgc2V0X3Jlc2NvcihyZXNjb3IgPSBGQUxTRSksDQogICAgICAgICAgICAgICAgZGF0YSA9IGRmX21vZGVsLCANCiAgICAgICAgICAgICAgICBwcmlvciA9IHByaW9ycywNCiAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjk3NSwgbWF4X3RyZWVkZXB0aCA9IDE0KSwNCiAgI3NhbXBsZV9wcmlvciA9ICJvbmx5IiwNCiAgc2F2ZV9wYXJzID0gc2F2ZV9wYXJzKGFsbCA9IFRSVUUpLA0KICBzZWVkID0gODUxMzIsIzE0NTQ4LA0KICAjaW5pdCA9IG15X2luaXRzLA0KICBpbml0X3IgPSAwLjUsDQogIGNoYWlucz00LCANCiAgaXRlcj01MDAwLCANCiAgY29yZXM9NCkNCg0Kc2F2ZShuMm9fbW9kNiwgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KYGBgDQoNCiMjIyBTdW1tYXJpemUgZml0DQpCZWxvdyBpcyBhIHN1bW1hcnkgb2YgdGhlIGZpdHRlZCBwYXJhbWV0ZXJzIGFuZCBNQ01DIGRpYWdub3N0aWNzLiANCmBgYHtyIHByaW50X21vZDYsIGVjaG89RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KDQpwcmludChuMm9fbW9kNiwgZGlnaXRzID0gMywgcHJpb3IgPSBUKQ0KYGBgDQoNCiMjIyBNb2RlbCBjaGVja3MNCkJlbG93LCB0aGUgc2FtZSBQUENzIGZvciBOMk8gYW5kIE4yTy1lcSB3ZXJlIGVtcGxveWVkIGFzIGJlZm9yZS4NCiMjIyMgTjJPIFBQQw0KVGhlIFBQQ3MgZm9yIE4yTyBmcm9tIHRoaXMgbW9kZWwgd2VyZSBzaW1pbGFybHkgcmVhc29uYWJsZSBhcyBmb3IgbW9kZWxzIDQgYW5kIDUgYWJvdmUuDQpgYGB7ciBwcGNfZnVsbF9jaGVja3NfbW9kX24ybzYsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQpncmlkLmFycmFuZ2UoDQpwcF9jaGVjayhuMm9fbW9kNiwgDQogICAgICAgICByZXNwID0gIm4ybyIsDQogICAgICAgICB0eXBlID0gImRlbnNfb3ZlcmxheSIsDQogICAgICAgICBuc2FtcGxlcyA9IDQwLA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJkZW5zaXR5IikNCiwNCnBwX2NoZWNrKG4yb19tb2Q2LCANCiAgICAgICAgIHJlc3AgPSAibjJvIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5zYW1wbGVzID0gNDAsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJjdW11bGF0aXZlIGRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWVhbiIsICJzZCIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q2LCANCiAgICAgICAgIHJlc3AgPSAibjJvIiwNCiAgICAgICAgIHR5cGUgPSAic3RhdF8yZCIsIA0KICAgICAgICAgc3RhdCA9IGMoImt1cnRvc2lzIiwgInNrZXduZXNzIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm8iLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q2LCANCiAgICAgICAgIHJlc3AgPSAibjJvIiwNCiAgICAgICAgIHR5cGUgPSAic2NhdHRlcl9hdmciLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwgbmNvbCA9IDIpDQpgYGANCg0KIyMjIyBFcXVpbGlicml1bSBOMk8gUFBDDQpBZ2FpbiwgdGhlIFBQQ3MgZm9yIE4yTy1lcSBpbiB0aGlzIG1vZGVsIHdlcmUgc2ltaWxhciB0byB0aG9zZSBmb3IgbW9kZWxzIDQgYW5kIDUuDQpgYGB7ciBwcGNfZnVsbF9jaGVja3NfbW9kX24yb2VxNiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDYucmRhIikNCmdyaWQuYXJyYW5nZSgNCnBwX2NoZWNrKG4yb19tb2Q2LCANCiAgICAgICAgIHJlc3AgPSAibjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJkZW5zX292ZXJsYXkiLA0KICAgICAgICAgbnNhbXBsZXMgPSA0MCwNCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkgKw0KICB4bGFiKGV4cHJlc3Npb24ocGFzdGUoImxvZyhFcXVpbGlicml1bSBOIlsyXSwiTykgY29uY2VudHJhdGlvbiIpKSkgKyANCiAgeWxhYigiZGVuc2l0eSIpDQosDQpwcF9jaGVjayhuMm9fbW9kNiwgDQogICAgICAgICByZXNwID0gIm4yb2VxIiwNCiAgICAgICAgIHR5cGUgPSAiZWNkZl9vdmVybGF5IiwNCiAgICAgICAgIG5zYW1wbGVzID0gNDAsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgibG9nKEVxdWlsaWJyaXVtIE4iWzJdLCJPKSBjb25jZW50cmF0aW9uIikpKSArIA0KICB5bGFiKCJjdW11bGF0aXZlIGRlbnNpdHkiKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJtZWFuIiwgInNkIiksIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KcHBfY2hlY2sobjJvX21vZDYsIA0KICAgICAgICAgcmVzcCA9ICJuMm9lcSIsDQogICAgICAgICB0eXBlID0gInN0YXRfMmQiLCANCiAgICAgICAgIHN0YXQgPSBjKCJrdXJ0b3NpcyIsICJza2V3bmVzcyIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q2LCANCiAgICAgICAgIHJlc3AgPSAibjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzdGF0XzJkIiwgDQogICAgICAgICBzdGF0ID0gYygibWluIiwgIm1heCIpLCANCiAgICAgICAgIGNvcmVzID0gMSkgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCnBwX2NoZWNrKG4yb19tb2Q2LCANCiAgICAgICAgIHJlc3AgPSAibjJvZXEiLA0KICAgICAgICAgdHlwZSA9ICJzY2F0dGVyX2F2ZyIsIA0KICAgICAgICAgY29yZXMgPSAxKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIEJpdmFyaWF0ZSBQUEMNClRoaXMgbW9kZWwgYWdhaW4gcHJvdmlkZWQgYSB2ZXJ5IHJlYXNvbmFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIGJpdmFyaWF0ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBOMk8gYW5kIE4yTy1lcSAoYmVsb3cpLg0KYGBge3IgcHBjX2J2X2NoZWNrX21vZF9uMm82LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBjKCJuMm8iLCJuMm9lcSIpLA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvZyhuMm9fb2JzKSwgeSA9IGxvZyhuMm9lcV9vYnMpKSkgKw0KICBnZW9tX2RlbnNpdHlfMmQoYWVzKHggPSBsb2cobjJvKSwgDQogICAgICAgICAgICAgICAgICAgICAgeSA9IGxvZyhuMm9lcSksIA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gLmRyYXcpLA0KICAgICAgICAgICAgICAgICAgYmlucyA9IDEwLA0KICAgICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIiwgDQogICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX2RlbnNpdHlfMmQoY29sb3IgPSAiYmxhY2siLCBiaW5zID0gMTApICsNCiAgeGxpbSgxLjI1LCAyLjc1KSArDQogIHlsaW0oMS4yNSwgMi43NSkgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQojIyMjIFNhdHVyYXRpb24gUFBDDQpUaGUgc2F0dXJhdGlvbiByYXRpbyBQUENzIGJlbG93IHNob3cgc2ltaWxhciBiZWhhdmlvciBhcyB3aXRoIG1vZGVscyA0IGFuZCA1IGFib3ZlLCBidXQgd2l0aCBwZXJoYXBzIHNsaWdodGx5IGxlc3MgYmlhcyBpbiB0aGUgcHJlZGljdGlvbnMgZm9yIHRoZSBwcm9wb3J0aW9uIG9mIHVuZGVyc2F0dXJhdGVkIHdhdGVyYm9kaWVzIGFuZCBmZXdlciBleHRyZW1lIHByZWRpY3Rpb25zIGZvciB0aGUgbWVhbnMgYW5kIHN0YW5kYXJkIGRldmlhdGlvbnMuIFRoZSBvYnNlcnZlZCBfdnMuXyBwcmVkaWN0ZWQgUFBDIGFsc28gYXBwZWFycyB0byBoYXZlIGEgYmV0dGVyIGJlaGF2ZWQgdmFyaWFuY2UgYW5kIG5vIGV4dHJlbWUgcHJlZGljdGlvbnMsIGNvbXBhcmVkIHRvIG1vZGVscyA0IGFuZCA1IHdpdGggdGhlIGxvZ25vcm1hbCBlcnJvcnMuDQpgYGB7ciBwcGNfc2F0X2NoZWNrX21vZF9uMm82LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBjKCJuMm8iLCAibjJvZXEiKSwNCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gbjJvIC8gbjJvZXEpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzYXRfcmF0aW8pKSArDQogIGdlb21fZGVuc2l0eShhZXMoeCA9IHNhdF9wcmVkLCBncm91cCA9IC5kcmF3KSwgDQogICAgICAgICAgICAgICBuID0gMTAyNCwgDQogICAgICAgICAgICAgICBhZGp1c3QgPSAxLA0KICAgICAgICAgICAgICAgY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBnZW9tX2RlbnNpdHkobiA9IDEwMjQsIGFkanVzdCA9IDIpICsNCiAgeGxpbSgwLCA1KSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgcmVzcCA9IGMoIm4ybyIsICJuMm9lcSIpLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHVzYXRfcHJlZCA9IGlmZWxzZShuMm8gPCBuMm9lcSwgMSwgMCkpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3ByZWQgPSBzdW0odXNhdF9wcmVkKSAvIDk4NCkgJT4lDQogIGdncGxvdChhZXMoeCA9IHByb3BfcHJlZCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAwMSwgZmlsbCA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoZGF0YSA9IGRmX21vZGVsLCBtYXBwaW5nID0gYWVzKHhpbnRlcmNlcHQgPSBzdW0objJvIDwgbjJvX2VxKS85ODQpKSArDQogIHhsYWIoIlByb3BvcnRpb24gdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl9tb2RlbCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgcmVzcCA9IGMoIm4ybyIsICJuMm9lcSIpLCANCiAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSA1MDApICU+JQ0KICByZW5hbWUobjJvX29icyA9IG4ybywNCiAgICAgICAgIG4yb2VxX29icyA9IG4yb19lcSkgJT4lDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gLmNhdGVnb3J5LA0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IC5wcmVkaWN0aW9uKSAlPiUNCiAgbXV0YXRlKHNhdF9yYXRpbyA9IG4yb19vYnMgLyBuMm9lcV9vYnMsDQogICAgICAgICBzYXRfcHJlZCA9IG4ybyAvIG4yb2VxKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBtdXRhdGUobWVhbl95cmVwID0gbWVhbihzYXRfcHJlZCksDQogICAgICAgICBzZF95cmVwID0gc2Qoc2F0X3ByZWQpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKG1lYW5feSA9IG1lYW4oc2F0X3JhdGlvKSwNCiAgICAgICAgIHNkX3kgPSBzZChzYXRfcmF0aW8pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl95cmVwLCB5ID0gc2RfeXJlcCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWFuX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBzZF95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLA0KZGZfbW9kZWwgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBjKCJuMm8iLCAibjJvZXEiKSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBuMm8gLyBuMm9lcSkgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgbXV0YXRlKG1pbl95cmVwID0gbWluKHNhdF9wcmVkKSwNCiAgICAgICAgIG1heF95cmVwID0gbWF4KHNhdF9wcmVkKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZShtaW5feSA9IG1pbihzYXRfcmF0aW8pLA0KICAgICAgICAgbWF4X3kgPSBtYXgoc2F0X3JhdGlvKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1pbl95cmVwLCB5ID0gbWF4X3lyZXApKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nIikgKw0KICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0ID0gbWluX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBtYXhfeSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX21vZGVsICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICByZXNwID0gYygibjJvIiwgIm4yb2VxIiksIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gbjJvIC8gbjJvZXEpICU+JQ0KICBncm91cF9ieSgucm93KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpKSAlPiUgDQogIGZpbHRlciguZHJhdyA9PSAxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQpUaGUgcGxvdCBiZWxvdyBzaG93cyB0aGUgc2FtZSBQUEMsIGJ1dCBmb3IgdGhlICJ0ZXN0IiBvciBzZWNvbmQtdmlzdCBkYXRhLiBPdmVyYWxsLCB0aGUgbW9kZWwgbG9va2VkIHRvIHBlcmZvcm0gc2ltaWxhcmx5IGFzIHdpdGggdGhlIGRhdGEgdXNlZCB0byBmaXQgaXQuDQpgYGB7ciBwcGNfc2F0X2NoZWNrX3Rlc3RkYXRhX21vZF9uMm82LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfdGVzdC5yZGEiKQ0KZ3JpZC5hcnJhbmdlKA0KZGZfdGVzdCAlPiUNCiAgYWRkX3ByZWRpY3RlZF9kcmF3cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgcmVzcCA9IGMoIm4ybyIsICJuMm9lcSIpLA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZShzYXRfcmF0aW8gPSBuMm9fb2JzIC8gbjJvZXFfb2JzLA0KICAgICAgICAgc2F0X3ByZWQgPSBuMm8gLyBuMm9lcSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9kZW5zaXR5KGFlcyh4ID0gc2F0X3ByZWQsIGdyb3VwID0gLmRyYXcpLCANCiAgICAgICAgICAgICAgIG4gPSAxMDI0LCANCiAgICAgICAgICAgICAgIGFkanVzdCA9IDEsDQogICAgICAgICAgICAgICBjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fZGVuc2l0eShuID0gMTAyNCwgYWRqdXN0ID0gMikgKw0KICB4bGltKDAsIDUpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCiwNCmRmX3Rlc3QgJT4lDQogIGFkZF9wcmVkaWN0ZWRfZHJhd3MobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSBjKCJuMm8iLCAibjJvZXEiKSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgcmVuYW1lKG4yb19vYnMgPSBuMm8sDQogICAgICAgICBuMm9lcV9vYnMgPSBuMm9fZXEpICU+JQ0KICB0aWR5cjo6cGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IC5jYXRlZ29yeSwNCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAucHJlZGljdGlvbikgJT4lDQogIG11dGF0ZSh1c2F0X3ByZWQgPSBpZmVsc2UobjJvIDwgbjJvZXEsIDEsIDApKSAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UocHJvcF9wcmVkID0gc3VtKHVzYXRfcHJlZCkgLyA5NSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHByb3BfcHJlZCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAwMSwgZmlsbCA9ICJsaWdodGJsdWUiKSArDQogIGdlb21fdmxpbmUoZGF0YSA9IGRmX21vZGVsLCBtYXBwaW5nID0gYWVzKHhpbnRlcmNlcHQgPSBzdW0objJvIDwgbjJvX2VxKS85ODQpKSArDQogIHhsYWIoIlByb3BvcnRpb24gdW5kZXJzYXR1cmF0ZWQgd2F0ZXJib2RpZXMiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl90ZXN0ICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICByZXNwID0gYygibjJvIiwgIm4yb2VxIiksIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gbjJvIC8gbjJvZXEpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtZWFuX3lyZXAgPSBtZWFuKHNhdF9wcmVkKSwNCiAgICAgICAgIHNkX3lyZXAgPSBzZChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWVhbl95ID0gbWVhbihzYXRfcmF0aW8pLA0KICAgICAgICAgc2RfeSA9IHNkKHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3lyZXAsIHkgPSBzZF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lYW5feSksIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHNkX3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl90ZXN0ICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICByZXNwID0gYygibjJvIiwgIm4yb2VxIiksIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gbjJvIC8gbjJvZXEpICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIG11dGF0ZShtaW5feXJlcCA9IG1pbihzYXRfcHJlZCksDQogICAgICAgICBtYXhfeXJlcCA9IG1heChzYXRfcHJlZCkpICU+JSANCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobWluX3kgPSBtaW4oc2F0X3JhdGlvKSwNCiAgICAgICAgIG1heF95ID0gbWF4KHNhdF9yYXRpbykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtaW5feXJlcCwgeSA9IG1heF95cmVwKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Ymx1ZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZyIpICsNCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1pbl95KSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gbWF4X3kpLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQosDQpkZl90ZXN0ICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICByZXNwID0gYygibjJvIiwgIm4yb2VxIiksIA0KICAgICAgICAgICAgICAgICAgICAgIG5kcmF3cyA9IDUwMCkgJT4lDQogIHJlbmFtZShuMm9fb2JzID0gbjJvLA0KICAgICAgICAgbjJvZXFfb2JzID0gbjJvX2VxKSAlPiUNCiAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAuY2F0ZWdvcnksDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gLnByZWRpY3Rpb24pICU+JQ0KICBtdXRhdGUoc2F0X3JhdGlvID0gbjJvX29icyAvIG4yb2VxX29icywNCiAgICAgICAgIHNhdF9wcmVkID0gbjJvIC8gbjJvZXEpICU+JQ0KICBncm91cF9ieSgucm93KSAlPiUNCiAgbXV0YXRlKG1lYW5feXJlcCA9IG1lYW4oc2F0X3ByZWQpKSAlPiUgDQogIGZpbHRlciguZHJhdyA9PSAxKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IG1lYW5feXJlcCwgeSA9IHNhdF9yYXRpbykpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiKSArDQogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2ciKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KLCBuY29sID0gMikNCmBgYA0KDQojIyMjIFItc3F1YXJlDQpCZWxvdyBhcmUgZXN0aW1hdGVzIGZvciB0aGUgQmF5ZXNpYW4gJFJeMiQsIHdoaWNoIHdlcmUgbGFyZ2VseSBzaW1pbGFyIGZvciBOMk8gYW5kIE4yTy1lcSBhcyB3aXRoIG1vZGVscyA0IGFuZCA1IGFib3ZlLiBUaGUgJFJeMiQgZm9yIHRoZSBzdXJmYWNlIHRlbXBlcmF0dXJlIHJlc3BvbnNlIGFsc28gc3VnZ2VzdGVkIGEgZmFpcmx5IGdvb2QgZml0Lg0KYGBge3IgcjJfbW9kX24ybzYsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9NH0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQpyb3VuZChiYXllc19SMihuMm9fbW9kNiwgcmVzcCA9ICJuMm8iKSwgMykgDQpyb3VuZChiYXllc19SMihuMm9fbW9kNiwgcmVzcCA9ICJuMm9lcSIpLCAzKQ0Kcm91bmQoYmF5ZXNfUjIobjJvX21vZDYsIHJlc3AgPSAic3VyZnRlbXAiKSwgMykNCmBgYA0KDQpCZWxvdyBhcmUgdGhlIHNhbWUgJFJeMiQgZXN0aW1hdGVzLCBidXQgZm9yIHRoZSBzZWNvbmQtdmlzaXQgZGF0YS4gVGhhdCB0aGVzZSBlc3RpbWF0ZXMgYXJlIHNpbWlsYXIgdG8gdGhvc2UgZm9yIHRoZSBkYXRhIHVzZWQgdG8gZml0IHRoZSBtb2RlbCwgc3VnZ2VzdGluZyB0aGF0IHRoZSBtb2RlbCBtYXkgcGVyZm9ybSBzaW1pbGFybHkgd2VsbCBvdXQtb2Ytc2FtcGxlLg0KYGBge3IgcjJfdGVzdF9tb2RfbjJvNiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD00fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDYucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX3Rlc3QucmRhIikNCnJvdW5kKGJheWVzX1IyKG4yb19tb2Q2LCByZXNwID0gIm4ybyIsIG5ld2RhdGEgPSBkZl90ZXN0KSwgMykgDQpyb3VuZChiYXllc19SMihuMm9fbW9kNiwgcmVzcCA9ICJuMm9lcSIsIG5ld2RhdGEgPSBkZl90ZXN0KSwgMykNCnJvdW5kKGJheWVzX1IyKG4yb19tb2Q2LCByZXNwID0gInN1cmZ0ZW1wIiwgbmV3ZGF0YSA9IGRmX3Rlc3QpLCAzKQ0KYGBgDQoNCiMjIyBDb3ZhcmlhdGUgZWZmZWN0cw0KIyMjIyBOMk8NClRoZSBjb25kaXRpb25hbCBlZmZlY3RzIHBsb3QgZm9yIHRoZSBjb3ZhcmlhdGUgZWZmZWN0cyBOMk8gc3VnZ2VzdGVkIGEgc2ltaWxhciBlZmZlY3Qgb2YgTk8zLCBidXQgaW50ZXJlc3RpbmcgaW50ZXJhY3Rpb25zIGJldHdlZW4gTk8zIGFuZCBsYWtlIGFyZWEgYW5kIE5PMyBhbmQgc3VyZmFjZSB0ZW1wZXJhdHVyZS4gRm9yIGxha2UgYXJlYSwgdGhlIGVmZmVjdCB3YXMgZXN0aW1hdGVkIHRvIGJlIGxhcmdlciBhbmQgbW9yZSBuZWdhdGl2ZSBhdCB0aGUgaGlnaGVzdCBsZXZlbHMgb2YgTk8zOyBhbmQgc2xpZ2h0bHkgbmVnYXRpdmUgYXQgdGhlIGxvd2VzdCBsZXZlbCBvZiBOTzMuIEZvciBzdXJmYWNlIHRlbXBlcmF0dXJlLCB0aGUgZWZmZWN0IHdhcyBlc3RpbWF0ZWQgdG8gYmUgbGFyZ2VzdCBhbmQgcG9zaXRpdmUgYXQgdGhlIGhpZ2hlc3QgbGV2ZWwgb2YgTk8zOyBhbmQgbmVnYXRpdmUgYXQgdGhlIGxvd2VzdCBsZXZlbCBvZiBOTzMuDQpgYGB7ciBjb25kaXRpb25hbF9lZmZlY3RzX21vZF9uMm9GLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTR9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KDQpwMSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJuMm8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoIm5vM19jYXQiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwMiA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJuMm8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZWZmZWN0cyA9IGMoImxvZ19hcmVhOm5vM19jYXQiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KcDMgPC0gY29uZGl0aW9uYWxfZWZmZWN0cyhuMm9fbW9kNiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AgPSAibjJvIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJzdXJmdGVtcDpubzNfY2F0IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90ID0gRikNCg0KcGx0IDwtIGdnYXJyYW5nZShwbG90KHAxLCBwbG90ID0gRilbWzFdXSwgDQogICAgICAgICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dLA0KICAgICAgICAgICAgICAgICBwbG90KHAzLCBwbG90ID0gRilbWzFdXSkNCg0Kcm0ocDEsIHAyLCBwMykNCg0KYW5ub3RhdGVfZmlndXJlKHBsdCwgdG9wID0gdGV4dF9ncm9iKGV4cHJlc3Npb24ocGFzdGUoIk4yTzogY292YXJpYXRlIGVmZmVjdHMgb24gIiwgbXUpKSwgDQogICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpDQpgYGANCg0KVGhlIGVzdGltYXRlZCBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAkXHNpZ21hJCBzdWdnZXN0ZWQgYSBuZWdhdGl2ZSByZWxhdGlvbnNoaXAgd2l0aCBsb2coYXJlYSkgYW5kIGEgcG9zaXRpdmUgcmVsYXRpb25zaGlwLCBhZ2Fpbiwgd2l0aCBOTzMuDQpgYGB7ciBjb25kaXRpb25hbF9lZmZlY3RzX3NpZ21hX24yb0YsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Mn0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQoNCnAxIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm4ybyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRwYXIgPSAic2hhcGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibG9nX2FyZWEiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm4ybyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRwYXIgPSAic2hhcGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibm8zX2NhdCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIA0KICAgICAgICAgICAgICAgIHRvcCA9IHRleHRfZ3JvYihleHByZXNzaW9uKHBhc3RlKCJOMk86IGNvdmFyaWF0ZSBlZmZlY3RzIG9uICIsIHNoYXBlKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZSA9ICJib2xkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDE0KSkNCmBgYA0KDQojIyMjIEVxdWlsaWJyaXVtIE4yTw0KVGhlIGVzdGltYXRlZCBjb3ZhcmlhdGUgZWZmZWN0IG9uIE4yTyByZW1haW5lZCBsYXJnZWx5IHRoZSBzYW1lIGFzIGVzdGltYXRlZCBpbiB0aGUgcHJldmlvdXMgbW9kZWwuDQpgYGB7ciBjb25kaXRpb25hbF9lZmZlY3RzX21vZF9uMm9lcUYsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Mn0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19tb2Q2LnJkYSIpDQoNCnAxIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm4yb2VxIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJzdXJmdGVtcDpsb2dfZWxldiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnAyIDwtIGNvbmRpdGlvbmFsX2VmZmVjdHMobjJvX21vZDYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm4yb2VxIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGVmZmVjdHMgPSBjKCJsb2dfZWxldjpzdXJmdGVtcCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGxvdCA9IEYpDQoNCnBsdCA8LSBnZ2FycmFuZ2UocGxvdChwMSwgcGxvdCA9IEYpW1sxXV0sDQogICAgICAgICAgICAgICAgIHBsb3QocDIsIHBsb3QgPSBGKVtbMV1dKQ0KDQpybShwMSwgcDIpDQoNCmFubm90YXRlX2ZpZ3VyZShwbHQsIHRvcCA9IHRleHRfZ3JvYihleHByZXNzaW9uKHBhc3RlKCJFcXVpbGlicml1bSBOMk86IGNvdmFyaWF0ZSBlZmZlY3RzIG9uICIsIG11KSksIA0KICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBzaXplID0gMTQpKQ0KYGBgDQoNCmBgYHtyIGNvbmRpdGlvbmFsX2VmZmVjdHNfc2lnbWFfbjJvZXFGLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTJ9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KDQpwMSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJuMm9lcSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRwYXIgPSAic2hhcGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygic3VyZnRlbXAiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwMiA8LSBjb25kaXRpb25hbF9lZmZlY3RzKG4yb19tb2Q2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9ICJuMm9lcSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRwYXIgPSAic2hhcGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBlZmZlY3RzID0gYygibG9nX2VsZXYiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHBsb3QgPSBGKQ0KDQpwbHQgPC0gZ2dhcnJhbmdlKHBsb3QocDEsIHBsb3QgPSBGKVtbMV1dLA0KICAgICAgICAgICAgICAgICBwbG90KHAyLCBwbG90ID0gRilbWzFdXSkNCg0Kcm0ocDEsIHAyKQ0KDQphbm5vdGF0ZV9maWd1cmUocGx0LCB0b3AgPSB0ZXh0X2dyb2IoZXhwcmVzc2lvbihwYXN0ZSgiRXF1aWxpYnJpdW0gTjJPOiBjb3ZhcmlhdGUgZWZmZWN0cyBvbiAiLCBzaGFwZSkpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkNCmBgYA0KDQojIFByZWRpY3QgdG8gcG9wdWxhdGlvbg0KQXMgcHJldmlvdXNseSBkZXNjcmliZWQsIGluIG9yZGVyIHRvIG1ha2UgaW5mZXJlbmNlcyB0byB0aGUgcG9wdWxhdGlvbiBvZiBpbnRlcmVzdCwgdGhlIGZpbmFsIG1vZGVsIGFib3ZlIHdhcyB1c2VkIHRvLCBmaXJzdCwgcHJlZGljdCBzdXJmYWNlIHRlbXBlcmF0dXJlIGluIHRoZSB0YXJnZXQgcG9wdWxhdGlvbiwgc2luY2UgaXQgZGVwZW5kZWQgb25seSBvbiB0aGUgZnVsbHkgb2JzZXJ2ZWQgY292YXJpYXRlcy4gTmV4dCwgdGhlIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9uIGZvciBzdXJmYWNlIHRlbXBlcmF0dXJlIHdhcyB1c2VkLCBhbG9uZyB3aXRoIHRoZSByZWxldmFudCBmdWxseSBvYnNlcnZlZCBjb3ZhcmlhdGVzLCB0byBwcmVkaWN0IE5PMyBpbiB0aGUgdGFyZ2V0IHBvcHVsYXRpb24uIEZpbmFsbHksIHRoZSBwcmVkaWN0aXZlIGRpc3RyaWJ1dGlvbnMgZm9yIHRlbXBlcmF0dXJlIGFuZCBOTzMgd2VyZSB1c2VkIHRvIHByZWRpY3QgdGhlIE4yTyByZXNwb25zZXMuIFRoZSBjb2RlIGZvciB0aGVzZSBzdGVwcyBpcyBvdXRsaW5lZCBpbiB0aGUgZm9sbG93aW5nLg0KDQpUaGUgZmlyc3Qgc3RlcCB1c2VkIHRoZSBmaW5hbCBtb2RlbCB0byBwcmVkaWN0IHRvIHRoZSBwb3B1bGF0aW9uOg0KYGBge3IgcHJlZGljdF9vYnNmcmFtZSwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2ZyYW1lLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KDQpwcmVkaWN0X3RlbXAgPC0gc2ZyYW1lICU+JQ0KICBtdXRhdGUoamRhdGUgPSAyMDUpICU+JQ0KICBhZGRfcHJlZGljdGVkX2RyYXdzKG4yb19tb2Q2LCByZXNwPWMoInN1cmZ0ZW1wIiksIA0KICAgICAgICAgICAgICAgICAgICAgIGFsbG93X25ld19sZXZlbHMgPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9MSwgDQogICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwKSAlPiUNCiAgbXV0YXRlKHN1cmZ0ZW1wID0gLnByZWRpY3Rpb24pDQoNCnNhdmUocHJlZGljdF90ZW1wLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3ByZWRpY3RfdGVtcC5yZGEiKQ0KYGBgDQoNCk5PMyB3YXMgbmV4dCBwcmVkaWN0ZWQuIE5vdGUgdGhhdCB0aGUgcG9zdGVyaW9yIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9uIGZvciBOTzMgd2FzIHN1YnNhbXBsZWQgaW4gb3JkZXIgdG8gbWluaW1pemUgZXhjZXNzIHNpbXVsYXRpb25zDQpgYGB7ciBwYXJhbGxlbF9wcmVkaWN0X2RyYXdzLCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fbW9kNi5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcHJlZGljdF90ZW1wLnJkYSIpDQoNCnRlbXBfWCA8LSBwcmVkaWN0X3RlbXAgJT4lICMgc2VsZWN0IHJlbGV2YW50IGNvbHVtbnMgYXMgcHJlZGljdG9ycw0KICB1bmdyb3VwKCkgJT4lDQogIHNlbGVjdChXU0E5LA0KICAgICAgICAgc3RhdGUsDQogICAgICAgICBzaXplX2NhdCwNCiAgICAgICAgIGxvZ19hcmVhLA0KICAgICAgICAgLnJvdywNCiAgICAgICAgIC5kcmF3LA0KICAgICAgICAgc3VyZnRlbXApICU+JQ0KICBzZWxlY3QoV1NBOSwgc3RhdGUsIHNpemVfY2F0LCBsb2dfYXJlYSwgc3VyZnRlbXApDQoNCg0Kcm0ocHJlZGljdF90ZW1wKSAjIHJlZHVjZSBtZW1vcnkNCmdjKCkNCg0KIyBzZXQgbnVtYmVyIG9mIGNvcmVzIHRvIHVzZSBmb3IgcGFyYWxsZWwgcHJlZGljdGlvbnMNCiMgYW5kIHJlZ2lzdGVyIHRoZSB3b3JrZXJzDQpjbCA8LSBwYXJhbGxlbDo6bWFrZUNsdXN0ZXIoNSkgDQpkb1NOT1c6OnJlZ2lzdGVyRG9TTk9XKGNsKSANCg0KIyBtYWtlIGEgcHJvZ3Jlc3MgYmFyDQpwYiA8LSB0eHRQcm9ncmVzc0JhcihtYXggPSAxNTAwLCBzdHlsZSA9IDMpDQpwcm9ncmVzcyA8LSBmdW5jdGlvbihuKSBzZXRUeHRQcm9ncmVzc0JhcihwYiwgbikNCm9wdHMgPC0gbGlzdChwcm9ncmVzcyA9IHByb2dyZXNzKQ0KDQpzeXN0ZW0udGltZSggIyBhcHByb3ggMjYgaHJzIHdpdGggNSB3b3JrZXJzICYgNTAwIGRyYXdzIGZyb20gUFBEDQpwcmVkaWN0X25vMyA8LSBmb3JlYWNoKHN1Yl9YID0gaXNwbGl0Um93cyh0ZW1wX1gsIGNodW5rU2l6ZSA9IDE1NTI5OSksIA0KICAgICAgICAgICAgICAgICAgICAgICAuY29tYmluZSA9ICdjJywNCiAgICAgICAgICAgICAgICAgICAgICAgLnBhY2thZ2VzID0gYygiYnJtcyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAub3B0aW9ucy5zbm93ID0gb3B0cw0KICAgICAgICAgICAgICAgICAgICAgICApICVkb3BhciUgew0KICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5KGJybXM6OnBvc3Rlcmlvcl9wcmVkaWN0KG4yb19tb2Q2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld2RhdGEgPSBzdWJfWCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwID0gIm5vM2NhdCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dfbmV3X2xldmVscyA9IFQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gMSksIDIsIHNhbXBsZSwgMSkNCiAgICAgICAgICAgICAgICAgICAgICAgICB9DQopDQoNCg0KY2xvc2UocGIpDQpwYXJhbGxlbDo6c3RvcENsdXN0ZXIoY2wpDQoNCnNhdmUocHJlZGljdF9ubzMsIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcHJlZGljdF9ubzMucmRhIikNCmBgYA0KDQpGaW5hbGx5LCBOMk8gYW5kIE4yTy1lcSB3ZXJlIHByZWRpY3RlZCB1c2luZyB0aGUgc3VyZmFjZSB0ZW1wZXJhdHVyZSBhbmQgbml0cmF0ZSBwcmVkaWN0aW9ucyBhbG9uZyB3aXRoIHRoZSBzdXJ2ZXkgdmFyaWFibGVzIGFuZCBrbm93biBjb3ZhcmlhdGVzLiBBZ2FpbiwgdGhlIHBvc3RlcmlvciB3YXMgc3Vic2FtcGxlZCBpbiBvcmRlciB0byByZWR1Y2UgZXhjZXNzIHNpbXVsYXRpb25zLg0KYGBge3IgbjJvX2NvdmFyaWF0ZXNfWCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcHJlZGljdF9ubzMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3ByZWRpY3RfdGVtcC5yZGEiKQ0KDQojIEFzc2VtYmxlIGRhdGFmcmFtZSBjb250YWluaW5nIHJlbGV2YW50IGNvdmFyaWF0ZXMgKGtub3duIGFuZCBwcmVkaWN0ZWQpDQpuMm9fWCA8LSBwcmVkaWN0X3RlbXAgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKG5vM19jYXQgPSBwcmVkaWN0X25vMykgJT4lDQogIHNlbGVjdChXU0E5LA0KICAgICAgICAgc3RhdGUsDQogICAgICAgICBzaXplX2NhdCwNCiAgICAgICAgIGxvZ19hcmVhLA0KICAgICAgICAgc3VyZnRlbXAsDQogICAgICAgICBsb2dfZWxldiwNCiAgICAgICAgIG5vM19jYXQpDQoNCiMgY2xlYXIgb2JqZWN0cyB0byByZWR1Y2UgbWVtb3J5IG92ZXJoZWFkDQpybShwcmVkaWN0X25vMywgcHJlZGljdF90ZW1wKSANCmdjKCkNCg0KIyBzYXZlIHRoZSBwcmVkaWN0b3JzIGZvciBuMm8gYW5kIG4yb2VxDQpzYXZlKG4yb19YLCBmaWxlID0gIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19YLnJkYSIpDQpgYGANCg0KYGBge3IgcGFyYWxsZWxfcHJlZGljdCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX21vZDYucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19YLnJkYSIpDQoNCiMgc2V0IG51bWJlciBvZiBjb3JlcyB0byB1c2UgZm9yIHBhcmFsbGVsIHByZWRpY3Rpb25zDQojIGFuZCByZWdpc3RlciB0aGUgd29ya2Vycw0KY2wgPC0gcGFyYWxsZWw6Om1ha2VDbHVzdGVyKDYpIA0KZG9TTk9XOjpyZWdpc3RlckRvU05PVyhjbCkgDQoNCiMgbWFrZSBhIHByb2dyZXNzIGJhcg0KcGIgPC0gdHh0UHJvZ3Jlc3NCYXIobWF4ID0gMTUwMCwgc3R5bGUgPSAzKQ0KcHJvZ3Jlc3MgPC0gZnVuY3Rpb24obikgc2V0VHh0UHJvZ3Jlc3NCYXIocGIsIG4pDQpvcHRzIDwtIGxpc3QocHJvZ3Jlc3MgPSBwcm9ncmVzcykNCg0KIyBtYWtlIHByZWRpY3Rpb25zIGluIHBhcmFsbGVsDQpzeXN0ZW0udGltZSgNCnByZWRpY3RfbjJvIDwtIGZvcmVhY2goc3ViX1ggPSBpc3BsaXRSb3dzKG4yb19YLCBjaHVua1NpemUgPSAxNTUyOTkpLA0KICAgICAgICAgICAgICAgICAuY29tYmluZSA9IHJiaW5kLA0KICAgICAgICAgICAgICAgICAub3B0aW9ucy5zbm93ID0gb3B0cywNCiAgICAgICAgICAgICAgICAgLnBhY2thZ2VzID0gYygiYnJtcyIpKSAlZG9wYXIlIHsNCiAgYXBwbHkocG9zdGVyaW9yX3ByZWRpY3QobjJvX21vZDYsDQogICAgICAgICAgICAgICAgICAgICAgICAgIG5ld2RhdGEgPSBzdWJfWCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcCA9IGMoIm4ybyIsICJuMm9lcSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd19uZXdfbGV2ZWxzID0gVCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gNTAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IDEpLA0KICAgICAgICAyLCBzYW1wbGUsIDEpDQogICAgICAgICAgICAgICAgICAgfQ0KKQ0KDQpjbG9zZShwYikNCnBhcmFsbGVsOjpzdG9wQ2x1c3RlcihjbCkNCg0KY29sbmFtZXMocHJlZGljdF9uMm8pIDwtIGMoIm4ybyIsICJuMm9lcSIpDQoNCnNhdmUocHJlZGljdF9uMm8sIGZpbGUgPSAiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcHJlZGljdF9uMm8ucmRhIikNCmBgYA0KDQpGaW5hbGx5LCB0aGUgcHJlZGljdGlvbnMgZm9yIGFsbCBmb3VyIHBhcnRpYWxseSBvYnNlcnZlZCByZXNwb25zZXMgd2VyZSBhc3NlbWJsZWQgaW50byBhIG5ldyBkYXRhZnJhbWUgZm9yIHVzZSBpbiBpbmZlcmVuY2UuDQpgYGB7ciBhc3NlbWJsZV9wcmVkaWN0aW9ucywgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvcHJlZGljdF9uMm8ucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3ByZWRpY3Rfbm8zLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9wcmVkaWN0X3RlbXAucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zIDwtIHByZWRpY3RfdGVtcCAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBtdXRhdGUobm8zY2F0ID0gcHJlZGljdF9ubzMpICU+JQ0KICBiaW5kX2NvbHMocHJlZGljdF9uMm8pICU+JQ0KICBtdXRhdGUobjJvc2F0ID0gbjJvIC8gbjJvZXEsICMgY2FsY3VsYXRlIHNhdHVyYXRpb24gcmF0aW8NCiAgICAgICAgIC5yb3cgPSByZXAoMTo0NjU4OTcsIGVhY2ggPSA1MDApLA0KICAgICAgICAgLmRyYXcgPSByZXAoc2VxKDEsNTAwLCAxKSwgNDY1ODk3KSkgJT4lDQogIG11dGF0ZShhcmVhX2hhID0gZXhwKGxvZ19hcmVhKSkgJT4lICMgaW5jbHVkZSBhcmVhIG9uIGhhIHNjYWxlDQogIHNlbGVjdChXU0E5LA0KICAgICAgICAgc3RhdGUsDQogICAgICAgICBzaXplX2NhdCwNCiAgICAgICAgIGFyZWFfaGEsDQogICAgICAgICBsYXQsDQogICAgICAgICBsb24sDQogICAgICAgICAucm93LA0KICAgICAgICAgLmRyYXcsDQogICAgICAgICBzdXJmdGVtcCwNCiAgICAgICAgIG5vM2NhdCwNCiAgICAgICAgIG4ybywNCiAgICAgICAgIG4yb2VxLA0KICAgICAgICAgbjJvc2F0KQ0KDQpybShwcmVkaWN0X24ybywgcHJlZGljdF90ZW1wLCBwcmVkaWN0X25vMykgIyBjbGVhbiB1cCB3b3Jrc3BhY2UgZm9yIFJBTQ0KZ2MoKQ0KIA0KDQpzYXZlKGFsbF9wcmVkaWN0aW9ucywgZmlsZSA9ICJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCmBgYA0KDQojIFBvcHVsYXRpb24gZXN0aW1hdGVzDQpBIG51bWJlciBvZiBlc3RpbWF0ZXMgZm9yIHRoZSB0YXJnZXQgcG9wdWxhdGlvbiB3ZXJlIGFzc2VtYmxlZCBhbmQgcHJlc2VudGVkIGJlbG93LiBGaXJzdCwgdGhlIGZ1bGwgcG9zdGVyaW9yIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9ucyBmb3IgZGlzc29sdmVkIE4yTywgZXF1aWxpYnJpdW0gTjJvLCBhbmQgdGhlIHNhdHVyYXRpb24gcmF0aW8gd2VyZSBhc3Nlc3NlZC4gVGhlc2UgZGlzdHJpYnV0aW9ucyBzdW1tYXJpemVkIHRoZSBwcmVkaWN0ZWQgZGlzdHJpYnV0aW9uIG9mIGNvbmNlbnRyYXRpb25zIG9yIHJhdGlvcyBmb3IgYWxsIGxha2VzIGluIHRoZSBwb3B1bGF0aW9uIG9mIGludGVyZXN0IGFuZCBpbmNsdWRlZCBwYXJhbWV0ZXIgdW5jZXJ0YWludHkgcHJvcGFnYXRlZCB0aHJvdWdoIHRoZSBtb2RlbC4gTmV4dCwgcG9wdWxhdGlvbiBtZWFucyB3ZXJlIGFzc2Vzc2VkLCBmb2xsb3dlZCBieSBjb21wYXJpc29ucyBvZiBzb21lIG1vZGVsLWJhc2VkIGVzdGltYXRlcyB0byBwcmV2aW91c2x5IGNhbGN1bGF0ZWQgZGVzaWduLWJhc2VkIGVzdGltYXRlcy4NCg0KIyMgUG9zdGVyaW9yIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9ucw0KQmVsb3csIGEgZGVuc2l0eSBwbG90IHN1bW1hcml6ZWQgdGhlIHBvc3RlcmlvciBwcmVkaWN0aXZlIGRpc3RyaWJ1dGlvbiBvZiBOMk8gYW5kIE4yTy1lcSBjb25jZW50cmF0aW9ucyBhY3Jvc3MgdGhlIHRhcmdldCBwb3B1bGF0aW9uIG9mIGxha2VzLCBiYXNlZCBvbiA1MDAgZHJhd3MgZnJvbSB0aGUgcG9zdGVyaW9yIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9uLiBOb3RlIHRoYXQgdGhlIHgtYXhpcyB3YXMgdHJ1bmNhdGVkIGF0IDUwIG5tb2wvTCBmb3IgYSBjbGVhcmVyIHZpc3VhbGl6YXRpb24gb2YgdGhlIGJ1bGsgb2YgdGhlIHByZWRpY3RlZCBkaXN0cmlidXRpb24uIEZvciByZWZlcmVuY2UsIHRoZSBtYXggcHJlZGljdGVkIHZhbHVlIHdhcyA0NDAzLjIgbm1vbC9MIGZvciBkaXNzb2x2ZWQgTjJPLCAyMC40IG5tb2wvTCBmb3IgZGlzc29sdmVkIE4yTywgYW5kIDc5My41IGZvciB0aGUgc2F0dXJhdGlvbiByYXRpby4gDQpgYGB7ciBwbG90X24yb19wb3N0ZXJpb3JfcHJlZHMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUgDQogIHNsaWNlX3NhbXBsZShuPTFlNCkgJT4lICMgc2ltcGxlIHJhbmRvbSBzYW1wbGUgMTBrIGxha2VzDQogIGdncGxvdChhZXMoeCA9IG4ybykpICsNCiAgc3RhdF9kaXN0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgc2NhbGVfeV9sb2cxMCgpICsNCiAgeGxpbSgwLCA1MCkgKw0KICB4bGFiKCJEaXNzb2x2ZWQgTjJPIGNvbmNlbnRyYXRpb24iKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KYGBge3IgcGxvdF9uMm9lcV9wb3N0ZXJpb3JfcHJlZHMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUgDQogIHNsaWNlX3NhbXBsZShuPTFlNCkgJT4lICMgc2ltcGxlIHJhbmRvbSBzYW1wbGUgMTBrIGxha2VzDQogIGdncGxvdChhZXMoeCA9IG4ybykpICsNCiAgc3RhdF9kaXN0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgc2NhbGVfeV9sb2cxMCgpICsNCiAgeGxpbSgwLCA1MCkgKw0KICB4bGFiKCJFcXVpbGlicml1bSBOMk8gY29uY2VudHJhdGlvbiIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpgYGB7ciBwbG90X3NhdF9wb3N0ZXJpb3JfcHJlZHMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUgDQogIHNsaWNlX3NhbXBsZShuPTFlNCkgJT4lICMgc2ltcGxlIHJhbmRvbSBzYW1wbGUgMTBrIGxha2VzDQogIGdncGxvdChhZXMoeCA9IG4yb3NhdCkpICsNCiAgc3RhdF9kaXN0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgc2NhbGVfeV9sb2cxMCgpICsNCiAgeGxpbSgwLCA4KSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgeGxhYigiTjJPIHNhdHVyYXRpb24gcmF0aW8iKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KIyMgRXN0aW1hdGVkIG1lYW5zDQojIyMgTmF0aW9uYWwNCkJlbG93IGFyZSBkZW5zaXR5IHBsb3RzIHN1bW1hcml6aW5nIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIF9tZWFuc18gZm9yIE4yTyBjb25jZW50cmF0aW9ucyBhbmQgdGhlIHNhdHVyYXRpb24gcmF0aW8gZm9yIHRoZSB0YXJnZXQgcG9wdWxhdGlvbiAoaS5lLiwgYWxsIFVTIGxha2VzID4gMWhhIGluIHRoZSBsb3dlciA0OCBzdGF0ZXMpLg0KYGBge3IgcGxvdF9uMm9fbmF0X3Bvc3Rlcmlvcl9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4ybykpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX24ybykpICsgDQogIHN0YXRfZGlzdF9zbGFiaW50ZXJ2YWwoLndpZHRoID0gYygwLjUsIDAuOTUpKSArDQogIHhsYWIoIm1lYW4gZGlzc29sdmVkIE4yTyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpgYGB7ciBwbG90X24yb2VxX25hdF9wb3N0ZXJpb3JfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JSANCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVhbihuMm9lcSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWFuX24ybykpICsgDQogIHN0YXRfZGlzdF9zbGFiaW50ZXJ2YWwoLndpZHRoID0gYygwLjUsIDAuOTUpKSArDQogIHhsYWIoIm1lYW4gZXF1bGlsaWJyaXVtIE4yTyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpgYGB7ciBwbG90X3NhdF9uYXRfcG9zdGVyaW9yX21lYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUgDQogIHN1bW1hcmlzZShtZWFuX3NhdCA9IG1lYW4objJvL24yb2VxKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5fc2F0KSkgKyANCiAgc3RhdF9kaXN0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigibWVhbiBOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpUbyBpbGx1c3RyYXRlIHRoZSBza2V3bmVzcyBpbiB0aGUgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24gZm9yIHRoZSBzYXR1cmF0aW9uIHJhdGlvLCBhbiBlc3RpbWF0ZSBmb3IgdGhlIG1lZGlhbiByYXRpbyBpcyBzaG93biBiZWxvdy4gVGhlIGVudGlyZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIHRoZSBtZWFuIGFib3ZlIGlzIGxhcmdlciB0aGFuIDEsIHRoZSByYXRpbyByZXByZXNlbnRpbmcgdGhlIGJvdW5kYXJ5IG9mIHVuZGVyLSBfdnMuXyBvdmVyc2F0dXJhdGlvbi4gQnkgY29tcGFyaXNvbiwgdGhlIHBvc3RlcmlvciBlc3RpbWF0ZSBvZiB0aGUgbWVkaWFuIGJlbG93IG9ubHkgaW5jbHVkZWQgdmFsdWVzIGxlc3MgdGhhbiBvbmUsIHN1Z2dlc3RpbmcgdGhhdCB0aG91Z2ggdGhlIG1lYW4gc2F0dXJhdGlvbiByYXRpbyB3YXMgZ3JlYXRlciB0aGFuIDEsIG1vc3QgbGFrZXMgaW4gdGhlIG5hdGlvbmFsIHBvcHVsYWl0b24gd2VyZSB1bmRlcnNhdHVyYXRlZCAoaS5lLiwgcmF0aW8gbGVzcyB0aGFuIDEpLiBJbiBkaXN0cmlidXRpb25zIHdpdGggcmlnaHQtc2tldywgdGhlIG1lYW4gY2FuIG9mdGVuIGJlIGNvbnNpZGVyYWJseSBsYXJnZXIgdGhhbiB0aGUgbWVkaWFuLg0KYGBge3IgcGxvdF9zYXRfbmF0X3Bvc3Rlcmlvcl9tZWRpYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUgDQogIHN1bW1hcmlzZShtZWRpYW5fc2F0ID0gbWVkaWFuKG4yby9uMm9lcSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtZWRpYW5fc2F0KSkgKyANCiAgc3RhdF9kaXN0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigibWVkaWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCkJlbG93IGlzIGEgcGxvdCBvZiB0aGUgcG9zdGVyaW9yIG1lYW4gZXN0aW1hdGUgZm9yIHRoZSBwcm9wb3J0aW9uIG9mIHVuc2F0dXJhdGVkIGxha2VzIGF0IHRoZSBuYXRpb25hbCBzY2FsZS4NCmBgYHtyIHBsb3RfdW5kZXJzYXRfcG9zdGVyaW9yX21lYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKHByb3Bfc2F0ID0gc3VtKG4yb3NhdCA8IDEpIC8gbGVuZ3RoKHVuaXF1ZSgucm93KSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBwcm9wX3NhdCkpICsgDQogIHN0YXRfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJQcm9wb3J0aW9uIG9mIHVuZGVyc2F0dXJhdGVkIHdhdGVyYm9kaWVzIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCiMjIyBFY29yZWdpb24NCkJlbG93IGFyZSBwb3N0ZXJpb3IgZXN0aW1hdGVzIG9mIHRoZSBtZWFucyBmb3IgZGlzc29sdmVkIGFuZCBlcXVpbGlicml1bSBOMk8gYW5kIHRoZSBzYXR1cmF0aW9uIHJhdGlvIGJ5IFdTQTkgZWNvcmVnaW9uLg0KYGBge3IgcGxvdF9uMm9fd3NhOV9wb3N0ZXJpb3JfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4ybyksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUoZWNvcmVnaW9uID0gV1NBOSkgJT4lDQogIGdncGxvdCgpICsgDQogIHN0YXRfc2xhYmludGVydmFsKGFlcyh4ID0gbWVhbl9uMm8sIA0KICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJlb3JkZXIoZWNvcmVnaW9uLCBtZWFuX24ybykpLCANCiAgICAgICAgICAgICAgICAgICAgcXVhbnRpbGVzID0gMTAwLA0KICAgICAgICAgICAgICAgICAgICAud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigibWVhbiBkaXNzb2x2ZWQgTjJPIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCmBgYHtyIHBsb3RfbjJvZXFfd3NhOV9wb3N0ZXJpb3JfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm9lcSA9IG1lYW4objJvZXEpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKGVjb3JlZ2lvbiA9IFdTQTkpICU+JQ0KICBnZ3Bsb3QoKSArIA0KICBzdGF0X3NsYWJpbnRlcnZhbChhZXMoeCA9IG1lYW5fbjJvZXEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJlb3JkZXIoZWNvcmVnaW9uLCBtZWFuX24yb2VxKSksIA0KICAgICAgICAgICAgICAgICAgICAud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigibWVhbiBlcXVpbGlicml1bSBOMk8iKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KYGBge3IgcGxvdF9zYXRfd3NhOV9wb3N0ZXJpb3JfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9zYXQgPSBtZWFuKG4yby9uMm9lcSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUoZWNvcmVnaW9uID0gV1NBOSkgJT4lDQogIGdncGxvdCgpICsgDQogIHN0YXRfc2xhYmludGVydmFsKGFlcyh4ID0gbWVhbl9zYXQsDQogICAgICAgICAgICAgICAgICAgICAgICB5ID0gcmVvcmRlcihlY29yZWdpb24sIG1lYW5fc2F0KSksDQogICAgICAgICAgICAgICAgICAgIC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJtZWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCkEgcGxvdCBvZiB0aGUgcG9zdGVyaW9yIGVzdGltYXRlcyBmb3IgdGhlIG1lZGlhbiBzYXR1cmF0aW9uIHJhdGlvIGJlbG93IGluZGljYXRlZCwgYWdhaW4sIHRoYXQgbW9zdCBsYWtlcyBpbiBlYWNoIGVjb3JlZ2lvbiB3ZXJlIHVuZGVyc2F0dXJhdGVkIChpLmUuLCBtZWRpYW4gPDwgMSkuDQpgYGB7ciBwbG90X3NhdF93c2E5X3Bvc3Rlcmlvcl9tZWRpYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KFdTQTksIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lZGlhbl9zYXQgPSBtZWRpYW4objJvL24yb2VxKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZShlY29yZWdpb24gPSBXU0E5KSAlPiUNCiAgZ2dwbG90KCkgKyANCiAgc3RhdF9zbGFiaW50ZXJ2YWwoYWVzKHggPSBtZWRpYW5fc2F0LA0KICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJlb3JkZXIoZWNvcmVnaW9uLCBtZWRpYW5fc2F0KSksDQogICAgICAgICAgICAgICAgICAgIC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJtZWRpYW4gTjJPIHNhdHVyYXRpb24gcmF0aW8iKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KQSBwbG90IG9mIHRoZSBlc3RpbWF0ZXMgb2YgdGhlIHByb3BvcnRpb24gb2YgdW5kZXItc2F0dXJhdGVkIGxha2VzIGJ5IGVjb3JlZ2lvbiBpcyBiZWxvdy4NCkEgcGxvdCBvZiB0aGUgcG9zdGVyaW9yIGVzdGltYXRlcyBmb3IgdGhlIG1lZGlhbiBzYXR1cmF0aW9uIHJhdGlvIGJlbG93IGluZGljYXRlZCwgYWdhaW4sIHRoYXQgbW9zdCBsYWtlcyBpbiBlYWNoIGVjb3JlZ2lvbiB3ZXJlIHVuZGVyc2F0dXJhdGVkIChpLmUuLCBtZWRpYW4gPDwgMSkuDQpgYGB7ciBwbG90X3Byb3Bfc2F0X3dzYTlfcG9zdGVyaW9yX21lZGlhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UocHJvcF9zYXQgPSBzdW0objJvc2F0IDwgMSkgLyBsZW5ndGgodW5pcXVlKC5yb3cpKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZShlY29yZWdpb24gPSBXU0E5KSAlPiUNCiAgZ2dwbG90KCkgKyANCiAgc3RhdF9zbGFiaW50ZXJ2YWwoYWVzKHggPSBwcm9wX3NhdCwNCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSByZW9yZGVyKGVjb3JlZ2lvbiwgcHJvcF9zYXQpKSwNCiAgICAgICAgICAgICAgICAgICAgLndpZHRoID0gYygwLjUsIDAuOTUpKSArDQogIHhsYWIoIlByb3BvcnRpb24gb2YgdW5kZXJzYXR1cmF0ZWQgbGFrZXMiKSArDQogIHlsYWIoImRlbnNpdHkiKSArDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KIyMjIFN0YXRlDQpDb21wYXJpc29ucyBvZiBtZWFuIGVzdGltYXRlcyAocG9zdGVyaW9yIG1lZGlhbiwgdXBwZXIgYW5kIGxvd2VyIDk1dGggcGVyY2VudGlsZXMpIGJ5IHN0YXRlIGFyZSBiZWxvdy4gRGVuc2l0eSBlc3RpbWF0ZXMgd2VyZSBub3QgaW5jbHVkZWQgdG8gbWluaW1pemUgcGxvdCBzcGFjZS4NCmBgYHtyIHBsb3Rfc3RhdGVfbWVhbl9uMm8sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHN0YXRlLCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lYW4objJvKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdyb3VwX2J5KHN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlID0gcm91bmQobWVkaWFuKG1lYW5fbjJvKSwgMSksDQogICAgTENMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC4wMjUpLCAxKSwNCiAgICBVQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjk3NSksIDEpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgc2VsZWN0KHN0YXRlLCBlc3RpbWF0ZSwgTENMLCBVQ0wpICU+JQ0KICBtdXRhdGUoc3RhdGUgPSBmb3JjYXRzOjpmY3RfcmVvcmRlcihzdGF0ZSwgZXN0aW1hdGUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3RhdGUsIHkgPSBlc3RpbWF0ZSApKSArDQogIGdlb21fcG9pbnQocG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTCwgeW1heCA9IFVDTCksDQogICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgeWxhYigibWVhbiBkaXNzb2x2ZWQgTjJPIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMocG9zaXRpb24gPSAibGVmdCIpICsgDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT05LCBhbmdsZT00NSkpDQpgYGANCg0KYGBge3IgcGxvdF9zdGF0ZV9tZWFuX24yb2VxLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzdGF0ZSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm9lcSA9IG1lYW4objJvZXEpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9uMm9lcSksIDEpLA0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvZXEsIHByb2JzID0gMC4wMjUpLCAxKSwNCiAgICBVQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24yb2VxLCBwcm9icyA9IDAuOTc1KSwgMSksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lIA0KICBzZWxlY3Qoc3RhdGUsIGVzdGltYXRlLCBMQ0wsIFVDTCkgJT4lDQogIG11dGF0ZShzdGF0ZSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKHN0YXRlLCBlc3RpbWF0ZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzdGF0ZSwgeSA9IGVzdGltYXRlICkpICsNCiAgZ2VvbV9wb2ludChwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMLCB5bWF4ID0gVUNMKSwNCiAgICAgICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICB5bGFiKCJtZWFuIGVxdWlsaWJyaXVtIE4yTyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gImxlZnQiKSArDQogIHRoZW1lX3RpZHliYXllcygpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT05LCBhbmdsZT00NSkpDQpgYGANCg0KQmVsb3csIGEgcGxvdCBvZiBlc3RpbWF0ZXMgZm9yIHRoZSBtZWFuIChibGFjayBjaXJjbGVzKSBhbmQgbWVkaWFuIChncmV5IGNpcmNsZXMpIHNhdHVyYXRpb24gcmF0aW8gYnkgc3RhdGUuIEEgaG9yaXpvbnRhbCwgZGFzaGVkLCBibGFjayBsaW5lIGlzIHNob3duIGF0IHJhdGlvID0gMSwgaW5kaWNhdGluZyB0aGUgYm91bmRhcnkgZm9yIHVuZGVyLSBfdnMuXyBvdmVyc2F0dXJhdGlvbi4gT25seSBhIGZldyBzdGF0ZXMgKGUuZy4sIE5WLCBERSkgaGFkIG1lZGlhbiBlc3RpbWF0ZXMgdGhhdCB3ZXJlIDEgb3IgZ3JlYXRlciwgc3VnZ2VzdGluZyB0aGF0LCBmb3IgbW9zdCBzdGF0ZXMsIG1vc3QgbGFrZXMgd2VyZSB1bmRlcnNhdHVyYXRlZC4NCmBgYHtyIHBsb3Rfc3RhdGVfbWVhbl9tZWRpYW5fc2F0LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzdGF0ZSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9zYXQgPSBtZWFuKG4yb3NhdCksIA0KICAgICAgICAgICAgbWVkaWFuX3NhdCA9IG1lZGlhbihuMm9zYXQpLA0KICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdyb3VwX2J5KHN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlX21lYW4gPSByb3VuZChtZWRpYW4obWVhbl9zYXQpLCA0KSwNCiAgICBMQ0xfbWVhbiA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuMDI1KSwgNCksDQogICAgVUNMX21lYW4gPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjk3NSksIDQpLA0KICAgIGVzdGltYXRlX21lZGlhbiA9IHJvdW5kKG1lZGlhbihtZWRpYW5fc2F0KSwgNCksDQogICAgTENMX21lZGlhbiA9IHJvdW5kKHF1YW50aWxlKG1lZGlhbl9zYXQsIHByb2JzID0gMC4wMjUpLCA0KSwNCiAgICBVQ0xfbWVkaWFuID0gcm91bmQocXVhbnRpbGUobWVkaWFuX3NhdCwgcHJvYnMgPSAwLjk3NSksIDQpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgc2VsZWN0KHN0YXRlLCANCiAgICAgICAgIGVzdGltYXRlX21lYW4sIA0KICAgICAgICAgZXN0aW1hdGVfbWVkaWFuLCANCiAgICAgICAgIExDTF9tZWFuLA0KICAgICAgICAgTENMX21lZGlhbiwNCiAgICAgICAgIFVDTF9tZWFuLA0KICAgICAgICAgVUNMX21lZGlhbikgJT4lDQogIG11dGF0ZShzdGF0ZSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKHN0YXRlLCBlc3RpbWF0ZV9tZWFuKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHN0YXRlLCB5ID0gZXN0aW1hdGVfbWVhbiApKSArDQogIGdlb21fcG9pbnQocG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSwNCiAgICAgICAgICAgICBzaXplID0gMikgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTF9tZWFuLCB5bWF4ID0gVUNMX21lYW4pLA0KICAgICAgICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBzdGF0ZSwgeSA9IGVzdGltYXRlX21lZGlhbiksIA0KICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSksDQogICAgICAgICAgICAgY29sb3IgPSAiZ3JleSIsDQogICAgICAgICAgICAgc2l6ZSA9IDIpICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHltaW4gPSBMQ0xfbWVkaWFuLCB5bWF4ID0gVUNMX21lZGlhbiksDQogICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSksDQogICAgICAgICAgICAgICAgIGNvbG9yID0gImdyYXkiKSArDQogIHlsYWIoIm1lYW4gYW5kIG1lZGlhbiBOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gImxlZnQiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9OSwgYW5nbGU9NDUpKQ0KYGBgDQoNCkZpbmFsbHksIGEgcGxvdCBvZiB0aGUgZXN0aW1hdGVkIHByb3BvcnRpb24gb2YgdW5kZXJzYXR1cmF0ZWQgbGFrZXMgZm9yIGVhY2ggc3RhdGUgaW4gdGhlIHRhcmdldCBwb3B1bGF0aW9uLiBQb2ludCBlc3RpbWF0ZXMgYXJlIHRoZSBwb3N0ZXJpb3IgbWVkaWFuIG9mIHRoZSBwcm9wb3J0aW9uIGFuZCBiYXJzIGFyZSB0aGUgdXBwZXIgYW5kIGxvd2VyIGJvdW5kYXJpZXMgb2YgdGhlIGNlbnRyYWwgOTV0aCBwZXJjZW50aWxlIG9mIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9ucyBvZiBwcm9wb3J0aW9ucy4NCmBgYHtyIHBsb3Rfc3RhdGVfcHJvcF9zYXQsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHN0YXRlLCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3NhdCA9IHN1bShuMm9zYXQgPCAxKSAvIGxlbmd0aCh1bmlxdWUoLnJvdykpLA0KICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdyb3VwX2J5KHN0YXRlKSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlID0gcm91bmQobWVkaWFuKHByb3Bfc2F0KSwgNCksDQogICAgTENMID0gcm91bmQocXVhbnRpbGUocHJvcF9zYXQsIHByb2JzID0gMC4wMjUpLCA0KSwNCiAgICBVQ0wgPSByb3VuZChxdWFudGlsZShwcm9wX3NhdCwgcHJvYnMgPSAwLjk3NSksIDQpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgc2VsZWN0KHN0YXRlLCANCiAgICAgICAgIGVzdGltYXRlLCANCiAgICAgICAgIExDTCwNCiAgICAgICAgIFVDTCkgJT4lDQogIG11dGF0ZShzdGF0ZSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKHN0YXRlLCBlc3RpbWF0ZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzdGF0ZSwgeSA9IGVzdGltYXRlKSkgKw0KICBnZW9tX3BvaW50KHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSksDQogICAgICAgICAgICAgc2l6ZSA9IDIpICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHltaW4gPSBMQ0wsIHltYXggPSBVQ0wpLA0KICAgICAgICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIHlsYWIoIlByb3BvcnRpb24gb2YgdW5kZXJzYXR1cmF0ZWQgbGFrZXMiKSArDQogIHNjYWxlX3lfY29udGludW91cyhwb3NpdGlvbiA9ICJsZWZ0IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9OSwgYW5nbGU9NDUpKQ0KYGBgDQoNCiMjIyBTaXplIGNhdGVnb3J5DQpUaGUgZXN0aW1hdGVkIG1lYW5zIGJ5IHNpemUgY2F0ZWdvcnkgYXJlIGJlbG93IGZvciBkaXNzb2x2ZWQgYW5kIGVxdWlsaWJyaXVtIE4yTyBhbmQgdGhlIHNhdHVyYXRpb24gcmF0aW8uIE1lZGlhbiBlc3RpbWF0ZXMgZm9yIHRoZSBzYXR1cmF0aW9uIHJhdGlvIGFyZSBhbHNvIHNob3duLg0KYGBge3IgcGxvdF9uMm9fc2l6ZV9wb3N0ZXJpb3JfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVhbihuMm8pLA0KICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5fbjJvLCB5ID0gc2l6ZV9jYXQpKSArIA0KICBzdGF0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigibWVhbiBkaXNzb2x2ZWQgTjJPIikgKw0KICB5bGFiKCJkZW5zaXR5IikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKQ0KYGBgDQoNCmBgYHtyIHBsb3RfbjJvZXFfc2l6ZV9wb3N0ZXJpb3JfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVhbihuMm9lcSksDQogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9uMm8sIHkgPSBzaXplX2NhdCkpICsgDQogIHN0YXRfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICB4bGFiKCJtZWFuIGVxdWlsaWJyaXVtIE4yTyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpgYGB7ciBwbG90X3NhdF9zaXplX3Bvc3Rlcmlvcl9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzaXplX2NhdCwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4yb3NhdCksDQogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbWVhbl9uMm8sIHkgPSBzaXplX2NhdCkpICsgDQogIHN0YXRfc2xhYmludGVydmFsKC53aWR0aCA9IGMoMC41LCAwLjk1KSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsNCiAgeGxhYigibWVhbiBOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpgYGB7ciBwbG90X3NhdF9zaXplX3Bvc3Rlcmlvcl9tZWRpYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lZGlhbihuMm9zYXQpLA0KICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdncGxvdChhZXMoeCA9IG1lYW5fbjJvLCB5ID0gc2l6ZV9jYXQpKSArIA0KICBzdGF0X3NsYWJpbnRlcnZhbCgud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siKSArDQogIHhsYWIoIm1lZGlhbiBOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpNZWFuIF92cy5fIG1lZGlhbiBiZWxvdy4NCmBgYHtyIHBsb3Rfc2l6ZV9jYXRfbWVhbl9tZWRpYW5fc2F0LCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzaXplX2NhdCwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9zYXQgPSBtZWFuKG4yb3NhdCksIA0KICAgICAgICAgICAgbWVkaWFuX3NhdCA9IG1lZGlhbihuMm9zYXQpLA0KICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0KSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlX21lYW4gPSByb3VuZChtZWRpYW4obWVhbl9zYXQpLCAyKSwNCiAgICBMQ0xfbWVhbiA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuMDI1KSwgMiksDQogICAgVUNMX21lYW4gPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjk3NSksIDIpLA0KICAgIGVzdGltYXRlX21lZGlhbiA9IHJvdW5kKG1lZGlhbihtZWRpYW5fc2F0KSwgMiksDQogICAgTENMX21lZGlhbiA9IHJvdW5kKHF1YW50aWxlKG1lZGlhbl9zYXQsIHByb2JzID0gMC4wMjUpLCAyKSwNCiAgICBVQ0xfbWVkaWFuID0gcm91bmQocXVhbnRpbGUobWVkaWFuX3NhdCwgcHJvYnMgPSAwLjk3NSksIDIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgc2VsZWN0KHNpemVfY2F0LCANCiAgICAgICAgIGVzdGltYXRlX21lYW4sIA0KICAgICAgICAgZXN0aW1hdGVfbWVkaWFuLCANCiAgICAgICAgIExDTF9tZWFuLA0KICAgICAgICAgTENMX21lZGlhbiwNCiAgICAgICAgIFVDTF9tZWFuLA0KICAgICAgICAgVUNMX21lZGlhbikgJT4lDQogIG11dGF0ZShzdGF0ZSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKHNpemVfY2F0LCBlc3RpbWF0ZV9tZWFuKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNpemVfY2F0LCB5ID0gZXN0aW1hdGVfbWVhbiApKSArDQogIGdlb21fcG9pbnQocG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSwNCiAgICAgICAgICAgICBzaXplID0gMikgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTF9tZWFuLCB5bWF4ID0gVUNMX21lYW4pLA0KICAgICAgICAgICAgICAgICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBzaXplX2NhdCwgeSA9IGVzdGltYXRlX21lZGlhbiksIA0KICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSksDQogICAgICAgICAgICAgY29sb3IgPSAiZ3JleSIsDQogICAgICAgICAgICAgc2l6ZSA9IDIpICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHltaW4gPSBMQ0xfbWVkaWFuLCB5bWF4ID0gVUNMX21lZGlhbiksDQogICAgICAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSksDQogICAgICAgICAgICAgICAgIGNvbG9yID0gImdyYXkiKSArDQogIHlsYWIoIm1lYW4gYW5kIG1lZGlhbiBOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gImxlZnQiKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9OSwgYW5nbGU9NDUpKQ0KYGBgDQoNCkFuZCwgZmluYWxseSwgdGhlIGVzdGltYXRlZCBwcm9wb3J0aW9uIG9mIHVuZGVyc2F0dXJhdGVkIGxha2VzIGluIHRoZSB0YXJnZXQgcG9wdWxhdGlvbiBieSBzaXplIGNhdGVnb3J5DQpgYGB7ciBwbG90X3Byb3Bfc2F0X3NpemVfY2F0X3Bvc3Rlcmlvcl9tZWRpYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KHNpemVfY2F0LCAuZHJhdykgJT4lDQogIHN1bW1hcmlzZShwcm9wX3NhdCA9IHN1bShuMm9zYXQgPCAxKSAvIGxlbmd0aCh1bmlxdWUoLnJvdykpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ2dwbG90KCkgKyANCiAgc3RhdF9zbGFiaW50ZXJ2YWwoYWVzKHggPSBwcm9wX3NhdCwNCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSByZW9yZGVyKHNpemVfY2F0LCBwcm9wX3NhdCkpLA0KICAgICAgICAgICAgICAgICAgICAud2lkdGggPSBjKDAuNSwgMC45NSkpICsNCiAgeGxhYigiUHJvcG9ydGlvbiBvZiB1bmRlcnNhdHVyYXRlZCBsYWtlcyIpICsNCiAgeWxhYigiZGVuc2l0eSIpICsNCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQojIyBNb2RlbC0gX3ZzLl8gZGVzaWduLWJhc2VkDQpCZWxvdywgZXN0aW1hdGVzIGZyb20gdGhlIG1vZGVsLWJhc2VkIGFwcHJvYWNoIGFyZSBjb21wYXJlZCB0byBkZXNpZ24tYmFzZWQgZXN0aW1hdGVzLiBJbiBnZW5lcmFsLCB0aGUgbW9kZWwgZXN0aW1hdGVzIHdlcmUgc2ltaWxhciB0byB0aGUgZGVzaWduLWJhc2VkIGVzdGltYXRlcy4gTW9kZWwgZXN0aW1hdGVzIHdlcmUgdHlwaWNhbGx5IHdpdGhpbiB0aGUgY29uZmlkZW5jZSBib3VuZHMgb2YgdGhlIGRlc2lnbi1iYXNlZCBlc3RpbWF0ZXMsIGJ1dCB3aXRoIG11Y2ggZ3JlYXRlciBwcmVjaXNpb24uIEltcHJvdmVkIHByZWNpc2lvbiB3YXMgZXhwZWN0ZWQgZHVlIHRvIHRoZSAic2hyaW5rYWdlIiBpbmR1Y2VkIGJ5IHRoZSBtdWx0aWxldmVsIHBhcmFtZXRlcml6YXRpb24sIHdoaWNoIGFsbG93ZWQgc29tZSAiYm9ycm93aW5nIiBvZiBpbmZvcm1hdGlvbiBhY3Jvc3MgdGhlIHZhcmlvdXMgbGV2ZWxzIG9mIHRoZSBzdXJ2ZXkgZmFjdG9ycy4gDQoNCiMjIyBEaXNzb2x2ZWQgTjJPDQpCZWxvdywgTmF0aW9uYWwgbWVhbiBlc3RpbWF0ZXMgZm9yIGRpc3NvbHZlZCBOMk8gZnJvbSB0aGUgbW9kZWwgYW5kIGRlc2lnbi1iYXNlZCBhcHByb2FjaGVzIHdlcmUgY29tcGFyZWQuIFRoZSBzYW1wbGUtYmFzZWQgZXN0aW1hdGUgd2FzIGFsc28gaW5jbHVkZWQgYXMgYSBuYWl2ZSByZWZlcmVuY2UuDQpgYGB7ciBuMm9fbWVhbnNfbmF0aW9uYWwsIG1lc3NhZ2U9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX3N1cnZleV9lc3RzLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lYW4objJvKSkgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX24ybyksIDIpLCAjIHBvc3RlcmlvciBtZWRpYW4NCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjAyNSksIDIpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuOTc1KSwgMikpICU+JSANCiAgbXV0YXRlKHR5cGUgPSAibW9kZWwiKSAlPiUNCiAgYmluZF9yb3dzKGNiaW5kKG4yb19zdXJ2ZXlfZXN0c1sxMCwgMjo0XSwgdHlwZSA9IHJlcCgic3VydmV5IiwgMSkpKSAlPiUNCiAgYWRkX3Jvdyhlc3RpbWF0ZSA9IHJvdW5kKG1lYW4oZGZfbW9kZWwkbjJvKSwgMiksDQogICAgICAgICAgdHlwZSA9ICJzYW1wbGUiKSAlPiUNCiAgcHJpbnQoKQ0KYGBgDQoNClRoZSBibGFjaywgdmVydGljYWwsIGRhc2hlZCBsaW5lIGluIHRoZSBmaWd1cmUgYmVsb3cgcmVwcmVzZW50cyB0aGUgbWVhbiBvZiB0aGUgc2FtcGxlLiANCmBgYHtyIHBsb3RfbjJvX21lYW5zX25hdGlvbmFsLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9MiwgZmlnLndpZHRoPTQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9kZl9tb2RlbC5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9uMm9fc3VydmV5X2VzdHMucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieSguZHJhdykgJT4lDQogIHN1bW1hcmlzZShtZWFuX24ybyA9IG1lYW4objJvKSkgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX24ybyksIDIpLCAjIHBvc3RlcmlvciBtZWRpYW4NCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjAyNSksIDIpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuOTc1KSwgMikpICU+JSANCiAgbXV0YXRlKHR5cGUgPSAibW9kZWwiKSAlPiUNCiAgYmluZF9yb3dzKGNiaW5kKG4yb19zdXJ2ZXlfZXN0c1sxMCwgMjo0XSwgdHlwZSA9IHJlcCgic3VydmV5IiwgMSkpKSAlPiUNCiAgbXV0YXRlKGNsX3dpZHRoID0gcm91bmQoVUNMIC0gTENMLCAyKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHR5cGUsIHkgPSBlc3RpbWF0ZSwgY29sb3IgPSB0eXBlKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIGdlb21fbGluZXJhbmdlKGFlcyh5bWluID0gTENMLCB5bWF4ID0gVUNMKSAsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsICJncmV5IikpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gcm91bmQobWVhbihkZl9tb2RlbCRuMm8pLCAyKSwgDQogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIiwNCiAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsNCiAgeWxhYigibWVhbiBOMk8gY29uY2VudHJhdGlvbiIpICsNCiAgZ2d0aXRsZSgiTmF0aW9uYWwgZXN0aW1hdGUgY29tcGFyaXNvbiIpICsNCiAgY29vcmRfZmxpcCgpICsgDQogIHRoZW1lX3RpZHliYXllcygpDQpgYGANCg0KQmVsb3csIGVzdGltYXRlcyB3ZXJlIGNvbXBhcmVkIGJ5IGVjb3JlZ2lvbi4NCmBgYHtyIG4yb19tZWFuX3dzYTksIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19zdXJ2ZXlfZXN0cy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KFdTQTksIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVhbihuMm8pKSAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX24ybyksIDIpLA0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuMDI1KSwgMiksDQogICAgVUNMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC45NzUpLCAyKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUgDQogIG11dGF0ZShlY29yZWdpb24gPSBmYWN0b3IoV1NBOSkpICU+JQ0KICBtdXRhdGUodHlwZSA9ICJtb2RlbCIpICU+JQ0KICBzZWxlY3QoZWNvcmVnaW9uLCBlc3RpbWF0ZSwgTENMLCBVQ0wsIHR5cGUpICU+JQ0KICBtdXRhdGUoZWNvcmVnaW9uID0gZm9yY2F0czo6ZmN0X3Jlb3JkZXIoZWNvcmVnaW9uLCBlc3RpbWF0ZSkpICU+JQ0KICBiaW5kX3Jvd3MoY2JpbmQobjJvX3N1cnZleV9lc3RzWy0xMCxdLCB0eXBlID0gcmVwKCJzdXJ2ZXkiLCA5KSkpICU+JQ0KICBhcnJhbmdlKGVjb3JlZ2lvbikgJT4lDQogIHByaW50KCkNCmBgYA0KDQpgYGB7ciBwbG90X21lYW5fbjJvX3dzYTksIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX3N1cnZleV9lc3RzLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoV1NBOSwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4ybyksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShXU0E5KSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlID0gcm91bmQobWVkaWFuKG1lYW5fbjJvKSwgMiksDQogICAgTENMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC4wMjUpLCAyKSwNCiAgICBVQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjk3NSksIDIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgbXV0YXRlKGVjb3JlZ2lvbiA9IGZhY3RvcihXU0E5KSkgJT4lDQogIG11dGF0ZSh0eXBlID0gIm1vZGVsIikgJT4lDQogIHNlbGVjdChlY29yZWdpb24sIGVzdGltYXRlLCBMQ0wsIFVDTCwgdHlwZSkgJT4lDQogIG11dGF0ZShlY29yZWdpb24gPSBmb3JjYXRzOjpmY3RfcmVvcmRlcihlY29yZWdpb24sIGVzdGltYXRlKSkgJT4lDQogIGJpbmRfcm93cyhjYmluZChuMm9fc3VydmV5X2VzdHNbLTEwLF0sIHR5cGUgPSByZXAoInN1cnZleSIsIDkpKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGVjb3JlZ2lvbiwgeSA9IGVzdGltYXRlLCBncm91cCA9IHR5cGUsIGNvbG9yID0gdHlwZSkpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTCwgeW1heCA9IFVDTCkgLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiYmxhY2siLCAiZ3JleSIpKSArDQogIGNvb3JkX2ZsaXAoKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHlsYWIoIm1lYW4gZGlzc29sdmVkIE4yTyIpICsNCiAgZ2d0aXRsZSgiRWNvcmVnaW9uIGVzdGltYXRlcyBjb21wYXJpc29uIikNCmBgYA0KDQpNZWFucyB3ZXJlIGNvbXBhcmVkIGFjY29yZGluZyB0byBzaXplIGNhdGVnb3JpZXMgYmVsb3cuDQpgYGB7ciB0YWJsZV9zaXplX21lYW5fbjJvLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTYsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL24yb19zdXJ2ZXlfZXN0c19zaXplLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fbjJvID0gbWVhbihuMm8pLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9uMm8pLCAxKSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX24ybywgcHJvYnMgPSAwLjAyNSksIDEpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuOTc1KSwgMSksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZSh0eXBlID0gIm1vZGVsIikgJT4lDQogIGJpbmRfcm93cyhjYmluZChuMm9fc3VydmV5X2VzdHNfc2l6ZSwgdHlwZSA9IHJlcCgic3VydmV5IiwgNSkpKSAlPiUNCiAgbXV0YXRlKHNpemUgPSBmYWN0b3Ioc2l6ZV9jYXQpKSAlPiUNCiAgbXV0YXRlKHNpemUgPSBmb3JjYXRzOjpmY3RfcmVvcmRlcihzaXplLCBlc3RpbWF0ZSkpICU+JQ0KICBtdXRhdGUoY2xfd2lkdGggPSBVQ0wgLSBMQ0wpICU+JQ0KICBhcnJhbmdlKHNpemUpICU+JQ0KICBzZWxlY3Qoc2l6ZSwgZXN0aW1hdGUsIExDTCwgVUNMLCB0eXBlKSAlPiUgDQogIHByaW50KCkNCmBgYA0KDQpgYGB7ciBwbG90X3NpemVfbWVhbl9uMm8sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvbjJvX3N1cnZleV9lc3RzX3NpemUucmRhIikNCg0KYWxsX3ByZWRpY3Rpb25zICU+JQ0KICBncm91cF9ieShzaXplX2NhdCwgLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9uMm8gPSBtZWFuKG4ybyksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBncm91cF9ieShzaXplX2NhdCkgJT4lDQogIHN1bW1hcmlzZShlc3RpbWF0ZSA9IHJvdW5kKG1lZGlhbihtZWFuX24ybyksIDIpLA0KICAgIExDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fbjJvLCBwcm9icyA9IDAuMDI1KSwgMiksDQogICAgVUNMID0gcm91bmQocXVhbnRpbGUobWVhbl9uMm8sIHByb2JzID0gMC45NzUpLCAyKSwNCiAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUgDQogICNtdXRhdGUoc2l6ZV9jYXQgPSBmYWN0b3Ioc2l6ZV9jYXQpKSAlPiUNCiAgbXV0YXRlKHR5cGUgPSAibW9kZWwiKSAlPiUNCiAgc2VsZWN0KHNpemVfY2F0LCBlc3RpbWF0ZSwgTENMLCBVQ0wsIHR5cGUpICU+JQ0KICBiaW5kX3Jvd3MoY2JpbmQobjJvX3N1cnZleV9lc3RzX3NpemUsIHR5cGUgPSByZXAoInN1cnZleSIsIDUpKSkgJT4lDQogIG11dGF0ZShzaXplX2NhdCA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKHNpemVfY2F0LCBlc3RpbWF0ZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzaXplX2NhdCwgeSA9IGVzdGltYXRlLCBncm91cCA9IHR5cGUsIGNvbG9yID0gdHlwZSkpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTCwgeW1heCA9IFVDTCkgLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiYmxhY2siLCAiZ3JleSIpKSArDQogIGNvb3JkX2ZsaXAoKSArIA0KICB0aGVtZV90aWR5YmF5ZXMoKSArDQogIHlsYWIoIm1lYW4gZGlzc29sdmVkIE4yTyIpICsNCiAgZ2d0aXRsZSgiU2l6ZSBjYXRlZ29yeSBlc3RpbWF0ZXMgY29tcGFyaXNvbiIpDQpgYGANCg0KIyMjIFNhdHVyYXRpb24NCkJlbG93LCB0aGUgc2FtZSBjb21wYXJpc29ucyB3ZXJlIG1hZGUgZm9yIHRoZSBzYXR1cmF0aW9uIGVzdGltYXRlcy4NCmBgYHtyIHRhYmxlX25hdF9zYXRfbWVhbiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvZGZfbW9kZWwucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2FsbF9wcmVkaWN0aW9ucy5yZGEiKQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvc2F0X3N1cnZleV9lc3RzLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoLmRyYXcpICU+JQ0KICBzdW1tYXJpc2UobWVhbl9zYXQgPSBtZWFuKG4yb3NhdCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9zYXQpLCAzKSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjAyNSksIDMpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgMyksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lIA0KICBtdXRhdGUodHlwZSA9ICJtb2RlbCIpICU+JQ0KICBiaW5kX3Jvd3MoY2JpbmQoc2F0X3N1cnZleV9lc3RzWzEwLCAyOjRdLCB0eXBlID0gcmVwKCJzdXJ2ZXkiLCAxKSkpICU+JQ0KICBhZGRfcm93KGVzdGltYXRlID0gcm91bmQobWVhbihkZl9tb2RlbCRuMm8gLyBkZl9tb2RlbCRuMm9fZXEpLCAzKSwNCiAgICAgICAgICB0eXBlID0gInNhbXBsZSIpICU+JQ0KICBwcmludCgpDQpgYGANCg0KYGBge3IgcGxvdF9uYXRfc2F0X21lYW4sIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD0yLCBmaWcud2lkdGg9NCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL2RmX21vZGVsLnJkYSIpDQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhdF9zdXJ2ZXlfZXN0cy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fc2F0ID0gbWVhbihuMm9zYXQpKSAlPiUNCiAgc3VtbWFyaXNlKGVzdGltYXRlID0gcm91bmQobWVkaWFuKG1lYW5fc2F0KSwgMyksDQogICAgTENMID0gcm91bmQocXVhbnRpbGUobWVhbl9zYXQsIHByb2JzID0gMC4wMjUpLCAzKSwNCiAgICBVQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjk3NSksIDMpKSAlPiUgIA0KICBtdXRhdGUodHlwZSA9ICJtb2RlbCIpICU+JQ0KICBiaW5kX3Jvd3MoY2JpbmQoc2F0X3N1cnZleV9lc3RzWzEwLCAyOjRdLCB0eXBlID0gcmVwKCJzdXJ2ZXkiLCAxKSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSB0eXBlLCB5ID0gZXN0aW1hdGUsIGNvbG9yID0gdHlwZSkpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTCwgeW1heCA9IFVDTCkgLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiYmxhY2siLCAiZ3JleSIpKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IHJvdW5kKG1lYW4oZGZfbW9kZWwkbjJvIC8gZGZfbW9kZWwkbjJvX2VxKSwgMyksIA0KICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIsDQogICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogIHlsYWIoIm1lYW4gTjJPIHNhdHVyYXRpb24gcmF0aW8iKSArDQogIGdndGl0bGUoIk5hdGlvbmFsIGVzdGltYXRlcyBjb21wYXJpc29uIikgKw0KICBjb29yZF9mbGlwKCkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KYGBge3IgcGxvdF93c2E5X3NhdF9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTYsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhdF9zdXJ2ZXlfZXN0cy5yZGEiKQ0KDQphbGxfcHJlZGljdGlvbnMgJT4lDQogIGdyb3VwX2J5KFdTQTksIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKCBtZWFuX3NhdCA9IG1lYW4objJvc2F0KSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIGdyb3VwX2J5KFdTQTkpICU+JQ0KICBzdW1tYXJpc2UoIGVzdGltYXRlID0gcm91bmQobWVkaWFuKG1lYW5fc2F0KSwgMyksDQogICAgTENMID0gcm91bmQocXVhbnRpbGUobWVhbl9zYXQsIHByb2JzID0gMC4wMjUpLCAzKSwNCiAgICBVQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjk3NSksIDMpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgbXV0YXRlKGVjb3JlZ2lvbiA9IGZhY3RvcihXU0E5KSkgJT4lDQogIG11dGF0ZSh0eXBlID0gIm1vZGVsIikgJT4lDQogIG11dGF0ZShlY29yZWdpb24gPSBmb3JjYXRzOjpmY3RfcmVvcmRlcihlY29yZWdpb24sIGVzdGltYXRlKSkgJT4lDQogIHNlbGVjdChlY29yZWdpb24sIGVzdGltYXRlLCBMQ0wsIFVDTCwgdHlwZSkgJT4lDQogIGJpbmRfcm93cyhjYmluZChzYXRfc3VydmV5X2VzdHNbLTEwLF0sIHR5cGUgPSByZXAoInN1cnZleSIsIDkpKSkgJT4lDQogIG11dGF0ZShjbF93aWR0aCA9IFVDTCAtIExDTCkgJT4lDQogIGdncGxvdChhZXMoeCA9IGVjb3JlZ2lvbiwgeSA9IGVzdGltYXRlLCBncm91cCA9IHR5cGUsIGNvbG9yID0gdHlwZSkpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbiA9IExDTCwgeW1heCA9IFVDTCkgLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiYmxhY2siLCAiZ3JleSIpKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGNvbG9yID0gImxpZ2h0Z3JleSIpICsNCiAgeWxhYigibWVhbiBOMk8gc2F0dXJhdGlvbiByYXRpbyIpICsNCiAgZ2d0aXRsZSgiRWNvcmVnaW9uIGVzdGltYXRlcyBjb21wYXJpc29uIikgKw0KICBjb29yZF9mbGlwKCkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQpgYGB7ciB0YWJsZV9zaXplX3NhdF9tZWFuLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTYsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsb2FkKCJDOi9Vc2Vycy9ybWFydGluL09uZURyaXZlIC0gRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKS9Eb2N1bWVudHMvQUVfUmVzZXJ2b2lycy9EaXNzb2x2ZWRHYXNObGEvbW9kZWxGaWxlcy9hbGxfcHJlZGljdGlvbnMucmRhIikNCmxvYWQoIkM6L1VzZXJzL3JtYXJ0aW4vT25lRHJpdmUgLSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IChFUEEpL0RvY3VtZW50cy9BRV9SZXNlcnZvaXJzL0Rpc3NvbHZlZEdhc05sYS9tb2RlbEZpbGVzL3NhdF9zdXJ2ZXlfZXN0c19zaXplLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fc2F0ID0gbWVhbihuMm9zYXQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9zYXQpLCAzKSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjAyNSksIDMpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgMykpICU+JQ0KICBtdXRhdGUodHlwZSA9ICJtb2RlbCIpICU+JQ0KICBiaW5kX3Jvd3MoY2JpbmQoc2F0X3N1cnZleV9lc3RzX3NpemUsIHR5cGUgPSByZXAoInN1cnZleSIsIDUpKSkgJT4lDQogIG11dGF0ZShzaXplID0gZmFjdG9yKHNpemVfY2F0KSkgJT4lDQogIG11dGF0ZShjbF93aWR0aCA9IFVDTCAtIExDTCkgJT4lDQogIGFycmFuZ2Uoc2l6ZSkgJT4lDQogIHNlbGVjdChzaXplLCBlc3RpbWF0ZSwgTENMLCBVQ0wsIHR5cGUpICU+JSANCiAgcHJpbnQoKQ0KYGBgDQoNCmBgYHtyIHBsb3Rfc2l6ZV9zYXRfbWVhbiwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbG9hZCgiQzovVXNlcnMvcm1hcnRpbi9PbmVEcml2ZSAtIEVudmlyb25tZW50YWwgUHJvdGVjdGlvbiBBZ2VuY3kgKEVQQSkvRG9jdW1lbnRzL0FFX1Jlc2Vydm9pcnMvRGlzc29sdmVkR2FzTmxhL21vZGVsRmlsZXMvYWxsX3ByZWRpY3Rpb25zLnJkYSIpDQoNCmFsbF9wcmVkaWN0aW9ucyAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQsIC5kcmF3KSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fc2F0ID0gbWVhbihuMm9zYXQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgZ3JvdXBfYnkoc2l6ZV9jYXQpICU+JQ0KICBzdW1tYXJpc2UoZXN0aW1hdGUgPSByb3VuZChtZWRpYW4obWVhbl9zYXQpLCAzKSwNCiAgICBMQ0wgPSByb3VuZChxdWFudGlsZShtZWFuX3NhdCwgcHJvYnMgPSAwLjAyNSksIDMpLA0KICAgIFVDTCA9IHJvdW5kKHF1YW50aWxlKG1lYW5fc2F0LCBwcm9icyA9IDAuOTc1KSwgMyksDQogICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZSh0eXBlID0gIm1vZGVsIikgJT4lDQogIGJpbmRfcm93cyhjYmluZChzYXRfc3VydmV5X2VzdHNfc2l6ZSwgdHlwZSA9IHJlcCgic3VydmV5IiwgNSkpKSAlPiUNCiAgbXV0YXRlKHNpemUgPSBmYWN0b3Ioc2l6ZV9jYXQpKSAlPiUNCiAgc2VsZWN0KHNpemUsIGVzdGltYXRlLCBMQ0wsIFVDTCwgdHlwZSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBzaXplLCB5ID0gZXN0aW1hdGUsIGdyb3VwID0gdHlwZSwgY29sb3IgPSB0eXBlKSkgKw0KICBnZW9tX3BvaW50KHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpICsNCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHltaW4gPSBMQ0wsIHltYXggPSBVQ0wpICwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2Uod2lkdGg9MC41KSkgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwgImdyZXkiKSkgKw0KICB5bGFiKCJtZWFuIE4yTyBzYXR1cmF0aW9uIHJhdGlvIikgKw0KICBnZ3RpdGxlKCJTaXplIGNhdGVnb3J5IGVzdGltYXRlcyBjb21wYXJpc29uIikgKw0KICBjb29yZF9mbGlwKCkgKyANCiAgdGhlbWVfdGlkeWJheWVzKCkNCmBgYA0KDQojIFJlZmVyZW5jZXMNCg0KIyBTZXNzaW9uIEluZm8NCmBgYHtyIHNlc3Npb259DQpzZXNzaW9uSW5mbygpDQpgYGA=